Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
95f8d886
提交
95f8d886
authored
3月 07, 2026
作者:
coderBryanFu
浏览文件
操作
浏览文件
下载
差异文件
fix:概览页打压遏制时间线模块修改
上级
893053c8
5ab89f5c
隐藏空白字符变更
内嵌
并排
正在显示
33 个修改的文件
包含
1909 行增加
和
1080 行删除
+1909
-1080
bill.js
src/api/bill.js
+1
-1
billHome.js
src/api/bill/billHome.js
+3
-3
RiskSignal.vue
src/components/RiskSignal/RiskSignal.vue
+1
-1
SearchContainer.vue
src/components/SearchContainer.vue
+13
-17
AiTipPane.vue
src/components/base/panes/AiTipPane.vue
+62
-0
common.scss
src/styles/common.scss
+42
-32
container.scss
src/styles/container.scss
+0
-2
descriptions.scss
src/styles/descriptions.scss
+12
-9
tabs.scss
src/styles/tabs.scss
+57
-33
index.vue
...ew/components/fourSuppress/components/addDomain/index.vue
+16
-4
index.vue
...w/components/fourSuppress/components/allElement/index.vue
+131
-65
index.vue
...omponents/fourSuppress/components/allGovernment/index.vue
+15
-36
index.vue
...iew/components/fourSuppress/components/allUnion/index.vue
+50
-19
ResourceLibrarySection.vue
src/views/bill/billHome/ResourceLibrarySection.vue
+2
-2
index.vue
src/views/bill/billHome/index.vue
+1
-1
index.vue
src/views/bill/billLayout/index.vue
+1
-1
STimeline.vue
src/views/bill/introdoction/STimeline.vue
+3
-3
index.vue
src/views/bill/introdoction/index.vue
+2
-2
capitalScale.vue
src/views/companyPages2/component/capitalScale.vue
+1
-1
SanctionsSituation.vue
...anyPages2/component/operatingPages/SanctionsSituation.vue
+256
-0
index.vue
src/views/companyPages2/component/operatingPages/index.vue
+20
-6
index.vue
src/views/companyPages2/index.vue
+2
-2
index.vue
src/views/coopRestriction/components/dataNew/index.vue
+1
-1
index.vue
src/views/coopRestriction/index.vue
+1
-1
index.vue
src/views/decree/decreeHome/index.vue
+1
-1
index.vue
src/views/exportControl/index.vue
+193
-82
RelationGraph.vue
...nction/components/deepMining/components/RelationGraph.vue
+801
-0
index.vue
...ontrol/v2.0SingleSanction/components/deepMining/index.vue
+145
-691
index.vue
src/views/finance/index.vue
+1
-1
index.vue
src/views/ruleRestriction/index.vue
+8
-3
index2.vue
src/views/ruleRestriction/index2.vue
+41
-40
index.vue
src/views/scientificFunding/index.vue
+24
-19
vite.config.js
vite.config.js
+2
-1
没有找到文件。
src/api/bill.js
浏览文件 @
95f8d886
...
...
@@ -20,7 +20,7 @@ export function getBillInfo(params) {
export
function
getBillPerson
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/
bill
/billInfoBean/person/
${
params
.
billId
}
`
,
url
:
`/
api
/billInfoBean/person/
${
params
.
billId
}
`
,
params
,
})
}
...
...
src/api/bill/billHome.js
浏览文件 @
95f8d886
...
...
@@ -111,7 +111,7 @@ export function getBillPostOrg(params) {
export
function
getBillProcess
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/
bill
/BillOverview/billsProcess/
${
params
.
year
}
`
,
url
:
`/
api
/BillOverview/billsProcess/
${
params
.
year
}
`
,
})
}
...
...
@@ -119,7 +119,7 @@ export function getBillProcess(params) {
export
function
getBills
(
params
,
signal
)
{
return
request
({
method
:
'GET'
,
url
:
`/
bill
/BillOverview/bills`
,
url
:
`/
api
/BillOverview/bills`
,
params
,
signal
})
...
...
@@ -129,7 +129,7 @@ export function getBills(params, signal) {
export
function
getBillsPerson
(
params
,
signal
)
{
return
request
({
method
:
'GET'
,
url
:
`/
bill
/BillOverview/billsPerson`
,
url
:
`/
api
/BillOverview/billsPerson`
,
params
,
signal
})
...
...
src/components/RiskSignal/RiskSignal.vue
浏览文件 @
95f8d886
...
...
@@ -16,7 +16,7 @@
<div
:class=
"
{
itemLeftStatus1: item[props.riskLevel] === '特别重大',
itemLeftStatus2: item[props.riskLevel] === '重大风险',
itemLeftStatus3: item[props.riskLevel] === '较大风险',
itemLeftStatus3: item[props.riskLevel] === '较大风险'
|| item[props.riskLevel] === '中等风险'
,
itemLeftStatus4: item[props.riskLevel] === '一般风险' || !item[props.riskLevel],
itemLeftStatus5: item[props.riskLevel] === '低风险',
}">
...
...
src/components/SearchContainer.vue
浏览文件 @
95f8d886
<
template
>
<div
class=
"search-container"
v-show=
"!isShow"
>
<div
class=
"search-type-tabs"
v-if=
"enableBillTypeSwitch"
>
<div
class=
"search-type-tab"
:class=
"
{ active: billSearchType === 'federal' }"
@click="handleChangeBillSearchType('federal')">
<div
class=
"search-type-tab"
:class=
"
{ active: billSearchType === 'federal' }"
@click="handleChangeBillSearchType('federal')"
>
联邦议会
</div>
<div
class=
"search-type-tab"
:class=
"
{ active: billSearchType === 'state' }"
@click="handleChangeBillSearchType('state')">
<div
class=
"search-type-tab"
:class=
"
{ active: billSearchType === 'state' }"
@click="handleChangeBillSearchType('state')"
>
州议会
</div>
</div>
<div
class=
"search-main"
:class=
"
{ 'search-main-with-tabs': enableBillTypeSwitch }">
<input
v-model=
"store.searchBillText"
:placeholder=
"placeholder"
@
keyup
.
enter=
"handleSearch"
class=
"search-input"
/>
<input
v-model=
"store.searchBillText"
:placeholder=
"placeholder"
@
keyup
.
enter=
"handleSearch"
class=
"search-input"
/>
<div
class=
"search-btn"
@
click=
"handleSearch"
>
<img
src=
"@/assets/icons/search-icon.png"
alt
/>
搜索
...
...
@@ -32,7 +37,7 @@
</div>
</div>
<div
class=
"btn"
@
click=
"handleToPosi('position2')"
>
<div
class=
"btn-text"
>
咨询
要闻
</div>
<div
class=
"btn-text"
>
资讯
要闻
</div>
<div
class=
"btn-icon"
>
<img
src=
"@/assets/icons/arrow-right-icon.png"
alt
/>
</div>
...
...
@@ -62,14 +67,7 @@ import { useWrittingAsstaintStore } from "@/stores/writtingAsstaintStore";
const
store
=
useWrittingAsstaintStore
();
const
router
=
useRouter
();
const
{
countInfo
,
containerRef
,
placeholder
,
areaName
,
enableBillTypeSwitch
,
defaultBillSearchType
}
=
defineProps
({
const
{
countInfo
,
containerRef
,
placeholder
,
areaName
,
enableBillTypeSwitch
,
defaultBillSearchType
}
=
defineProps
({
countInfo
:
{
type
:
Array
,
default
:
()
=>
[]
...
...
@@ -138,11 +136,9 @@ watchEffect(() => {
if
(
isShow
.
value
)
{
homeMainRef
.
value
.
classList
.
add
(
"scroll-main"
);
homeMainRef
.
value
.
classList
.
add
(
"scrollHomeMain"
);
}
else
{
homeMainRef
.
value
.
classList
.
remove
(
"scroll-main"
);
homeMainRef
.
value
.
classList
.
remove
(
"scrollHomeMain"
);
}
store
.
changeIsShowSearchBar
(
isShow
.
value
);
...
...
src/components/base/panes/AiTipPane.vue
0 → 100644
浏览文件 @
95f8d886
<
script
setup
>
</
script
>
<
template
>
<div
class=
"flex-display box"
>
<div
class=
"img"
></div>
<div
class=
"flex-fill txt text-tip-1"
>
<slot></slot>
</div>
<div
class=
"arrow"
><span>
→
</span></div>
</div>
</
template
>
<
style
scoped
lang=
"scss"
>
@use
'@/styles/common.scss'
;
.box
{
background-color
:
var
(
--
color-primary-2
);
flex-direction
:
row
;
gap
:
10px
;
justify-content
:
center
;
align-items
:
center
;
padding
:
6px
12px
;
border-radius
:
4px
;
border
:
1px
solid
var
(
--
color-primary-10
);
color
:
var
(
--
color-primary-100
);
}
.img
{
width
:
19px
;
height
:
20px
;
background-image
:
url("@/assets/icons/model.png")
;
}
.txt
{
flex
:
1
;
min-width
:
0
;
word-wrap
:
break-word
;
word-break
:
break-word
;
overflow-wrap
:
break-word
;
max-width
:
100%
;
}
.arrow
{
border-radius
:
50%
;
min-width
:
24px
;
width
:
24px
;
height
:
24px
;
background
:
var
(
--
color-primary-10
);
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
span
{
font-size
:
22px
;
font-weight
:
bold
;
position
:
relative
;
top
:
-3px
;
/* 向上偏移2px */
}
}
</
style
>
\ No newline at end of file
src/styles/common.scss
浏览文件 @
95f8d886
...
...
@@ -7,9 +7,14 @@
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
}
.flex-display
{
.flex-display
{
display
:
flex
;
}
.flex-fill
{
flex
:
1
;
}
// 文本超出指定行数省略号显示
@mixin
text-ellipsis
(
$line-clamp
)
{
overflow
:
hidden
;
...
...
@@ -26,64 +31,67 @@
word-break
:
break-word
;
/* 允许单词换行 */
}
//禁止换行
.text-nowrap
{
.text-nowrap
{
white-space
:
nowrap
;
}
/***文本样式***/
.text-base
{
color
:
var
(
--
color-primary-80
);
.text-base
{
color
:
var
(
--
color-primary-80
);
}
//0级标题
.text-title-0
{
.text-title-0
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
32px
;
}
.text-title-0-bold
{
.text-title-0-bold
{
@extend
.text-title-0
;
font-weight
:
Bold
;
}
.text-title-0-show
{
.text-title-0-show
{
@extend
.text-title-0
;
font-size
:
48px
;
font-family
:
"YouSheBiaoTiHei"
;
}
//1级标题
.text-title-1
{
.text-title-1
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
24px
;
}
.text-title-1-bold
{
.text-title-1-bold
{
@extend
.text-title-1
;
font-weight
:
Bold
;
}
.text-title-1-show
{
.text-title-1-show
{
@extend
.text-title-1
;
font-size
:
30px
;
font-family
:
"YouSheBiaoTiHei"
;
}
//2级标题
.text-title-2
{
.text-title-2
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
20px
;
line-height
:
26px
;
line-height
:
26px
;
}
.text-title-2-bold
{
.text-title-2-bold
{
@extend
.text-title-2
;
font-weight
:
Bold
;
}
.text-title-2-show
{
.text-title-2-show
{
@extend
.text-title-2
;
font-size
:
24px
;
font-family
:
"YouSheBiaoTiHei"
;
...
...
@@ -91,19 +99,19 @@
}
//3级标题
.text-title-3
{
.text-title-3
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
18px
;
line-height
:
24px
;
line-height
:
24px
;
}
.text-title-3-bold
{
.text-title-3-bold
{
@extend
.text-title-3
;
font-weight
:
Bold
;
}
.text-title-3-show
{
.text-title-3-show
{
@extend
.text-title-3
;
font-size
:
20px
;
font-family
:
"YouSheBiaoTiHei"
;
...
...
@@ -111,58 +119,60 @@
}
//正文
.text-regular
{
.text-regular
{
@extend
.text-base
;
font-size
:
16px
;
line-height
:
30px
;
line-height
:
30px
;
}
//正文-加粗
.text-bold
{
.text-bold
{
@extend
.text-base
;
font-weight
:
Bold
;
}
//正文-紧凑
.text-compact
{
.text-compact
{
@extend
.text-base
;
font-size
:
16px
;
line-height
:
24px
;
line-height
:
24px
;
}
.text-compact-bold
{
.text-compact-bold
{
@extend
.text-base
;
font-size
:
16px
;
line-height
:
24px
;
line-height
:
24px
;
font-weight
:
Bold
;
}
//1级提示文字
.text-tip-1
{
.text-tip-1
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
16px
;
line-height
:
24px
;
line-height
:
24px
;
}
.text-tip-1-bold
{
.text-tip-1-bold
{
@extend
.text-tip-1
;
font-weight
:
Bold
;
}
//2级提示文字
.text-tip-2
{
.text-tip-2
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
14px
;
line-height
:
22px
;
line-height
:
22px
;
}
.text-tip-2-bold
{
.text-tip-2-bold
{
@extend
.text-tip-2
;
font-weight
:
Bold
;
}
//3级提示文字
.text-tip-3
{
.text-tip-3
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
12px
;
...
...
src/styles/container.scss
浏览文件 @
95f8d886
@use
"common"
;
/***通用页面***/
.common-page
{
font-family
:
"Microsoft Yahei"
,
"PingFang SC"
,
sans-serif
;
margin
:
16px
auto
;
width
:
1600px
;
align-items
:
center
;
...
...
src/styles/descriptions.scss
浏览文件 @
95f8d886
@use
"common"
;
/***没有nav下划线***/
.common-descriptions
.el-descriptions__label
{
@extend
.text-tip-1-bold
;
color
:
var
(
--
text-primary-80-color
);
}
.common-descriptions
.el-descriptions__content
{
@extend
.text-tip-1
;
color
:
var
(
--
text-primary-80-color
);
/***通用描述组件***/
.common-descriptions
{
.el-descriptions__label
{
@extend
.text-tip-1-bold
;
color
:
var
(
--
text-primary-80-color
);
}
.common-descriptions
.el-descriptions__content
{
@extend
.text-tip-1
;
color
:
var
(
--
text-primary-80-color
);
}
}
\ No newline at end of file
src/styles/tabs.scss
浏览文件 @
95f8d886
@use
"common"
;
/***没有nav下划线***/
.
tabs-nav-no-wrap
.
el-tabs__nav-wrap
:
:
after
{
height
:
0px
!
important
;
width
:
0px
!
important
;
.tabs-nav-no-wrap
{
.
el-tabs__nav-wrap
:
:
after
{
height
:
0px
!
important
;
width
:
0px
!
important
;
}
}
/***nav as card***/
.tabs-header-as-card
.el-tabs__header
:not
(
.disinheritance
.el-tabs__header
)
{
@extend
.background-as-card
;
padding
:
2px
;
.tabs-header-as-card
{
.el-tabs__header
:not
(
.disinheritance
.el-tabs__header
)
{
@extend
.background-as-card
;
padding
:
2px
;
}
}
/***作为按钮样式的tabs-bar***/
/*选中无下划线*/
.tabs-bar-as-btn
.el-tabs__active-bar
:not
(
.disinheritance
.el-tabs__active-bar
)
{
height
:
0px
;
}
.tabs-bar-as-btn
{
.el-tabs__active-bar
:not
(
.disinheritance
.el-tabs__active-bar
)
{
height
:
0px
;
}
/*定义字体*/
.tabs-bar-as-btn
.el-tabs__item
:not
(
.disinheritance
.el-tabs__item
)
{
font-size
:
20px
;
font-family
:
"Source Han Sans CN-Regular"
;
font-weight
:
Regular
;
line-height
:
26px
;
height
:
50px
;
}
/*定义字体*/
.el-tabs__item
:not
(
.disinheritance
.el-tabs__item
)
{
font-size
:
20px
;
font-family
:
"Source Han Sans CN-Regular"
;
font-weight
:
Regular
;
line-height
:
26px
;
height
:
50px
;
}
/*激活时按钮样式*/
.tabs-bar-as-btn
.el-tabs__item.is-active
:not
(
.disinheritance
.el-tabs__item
)
{
/*激活时按钮样式*/
.el-tabs__item.is-active
:not
(
.disinheritance
.el-tabs__item
)
{
font-size
:
24px
;
font-family
:
"Source Han Sans CN-Bold"
;
font-weight
:
Bold
;
font-size
:
24px
;
font-family
:
"Source Han Sans CN-Bold"
;
font-weight
:
Bold
;
color
:
var
(
--
color-primary-100
);
border-width
:
1px
;
border-style
:
solid
;
border-color
:
var
(
--
color-primary-35
);
border-radius
:
10px
;
background-color
:
var
(
--
color-primary-2
);
color
:
var
(
--
color-primary-100
);
border-width
:
1px
;
border-style
:
solid
;
border-color
:
var
(
--
color-primary-35
);
border-radius
:
10px
;
background-color
:
var
(
--
color-primary-2
);
}
}
/***tabs-bar左边悬浮***/
.left-float-nav-tabs
.el-tabs__item
{
position
:relative
;
}
.left-float-nav-tabs
.el-tabs__item.is-active
{
background-color
:
aquamarine
;
.left-float-nav-tabs
{
// .el-tabs__header {
position
:
relative
;
overflow
:
visible
;
transform
:
translateZ
(
0
);
/* 双重保障 */
/* 创建新的渲染层 */
/* 创建新的层叠上下文 */
.el-tabs__header
{
// position: absolute;
left
:
0
;
top
:
0
;
z-index
:
999
;
background-color
:
red
;
// margin-left: -20px;
}
// }
}
\ No newline at end of file
src/views/ZMOverView/components/fourSuppress/components/addDomain/index.vue
浏览文件 @
95f8d886
...
...
@@ -74,7 +74,12 @@
<span>
美对华领域打压遏制最新动态
</span>
</div>
<div
class=
"title-right-select"
>
<el-select
v-model=
"selectedFieldForLatest"
placeholder=
"全部领域"
class=
"field-select"
>
<el-select
v-model=
"selectedFieldForLatest"
@
change=
"handleFieldChange"
placeholder=
"全部领域"
class=
"field-select"
>
<el-option
v-for=
"item in fieldOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
...
...
@@ -131,7 +136,7 @@
<simple-pagination
v-model:current-page=
"newsCurrentPage"
:page-size=
"pageSize"
:total=
"
n
ewsList.length"
:total=
"
allN
ewsList.length"
@
page-change=
"handleNewsPageChange"
/>
</div>
...
...
@@ -215,7 +220,7 @@
<div
class=
"bottom-item"
>
<div
class=
"bottom-item-title"
>
<img
:src=
"icon4"
alt=
""
/>
<span>
美对
我
领域打压遏制时间线
</span>
<span>
美对
华
领域打压遏制时间线
</span>
</div>
<el-select
v-model=
"selectedFieldTimeline"
...
...
@@ -408,6 +413,12 @@ const newsList = ref([]);
const
newsCurrentPage
=
ref
(
1
);
const
pageSize
=
ref
(
5
);
// 每页显示 5 条
const
handleFieldChange
=
domainId
=>
{
console
.
log
(
"领域改变"
,
domainId
);
console
.
log
(
"领域值 =>"
,
selectedFieldForLatest
.
value
);
getUSGovernmentLatestDynamicData
();
};
// 总页数
const
totalPages
=
computed
(()
=>
{
return
Math
.
ceil
(
newsList
.
value
.
length
/
pageSize
.
value
)
||
1
;
...
...
@@ -445,10 +456,11 @@ const handleNextPage = () => {
const
getUSGovernmentLatestDynamicData
=
async
()
=>
{
try
{
const
params
=
{
orgId
:
!!
deptValueForLatest
.
value
?
deptValue
ForLatest
.
value
:
null
,
domainId
:
!!
selectedFieldForLatest
.
value
?
selectedField
ForLatest
.
value
:
null
,
pageSize
:
50
,
currentPage
:
newsCurrentPage
.
value
};
console
.
log
(
"领域值 =>"
,
selectedFieldForLatest
.
value
);
const
res
=
await
getUSGovernmentLatestDynamic
(
params
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
// 将接口数据转换为 newsList 需要的格式
...
...
src/views/ZMOverView/components/fourSuppress/components/allElement/index.vue
浏览文件 @
95f8d886
...
...
@@ -9,13 +9,18 @@
</div>
<div
class=
"cards-mask"
>
<div
class=
"item-box"
:style=
"
{ transform: `translateX(-${currentIndex * (307 + 16)}px)` }">
<div
class=
"header-item"
:class=
"
{
headerItem1: index % 5 === 0,
headerItem2: index % 5 === 1,
headerItem3: index % 5 === 2,
headerItem4: index % 5 === 3,
headerItem5: index % 5 === 4
}" v-for="(item, index) in headerList" :key="index">
<div
class=
"header-item"
:class=
"
{
headerItem1: index % 5 === 0,
headerItem2: index % 5 === 1,
headerItem3: index % 5 === 2,
headerItem4: index % 5 === 3,
headerItem5: index % 5 === 4
}"
v-for="(item, index) in headerList"
:key="index"
>
<div
class=
"name"
>
{{
item
.
elementName
}}
</div>
<div
class=
"num"
>
{{
item
.
num
}}
</div>
</div>
...
...
@@ -32,8 +37,12 @@
<div
class=
"title"
>
{{
"最新动态"
}}
</div>
</div>
<div
class=
"box1-main"
>
<div
class=
"box1-item"
v-for=
"(item, index) in box1DataList"
:key=
"index"
@
click=
"handleToDecreeDetail(item)"
>
<div
class=
"box1-item"
v-for=
"(item, index) in box1DataList"
:key=
"index"
@
click=
"handleToDecreeDetail(item)"
>
<div
class=
"box1-item-left"
>
{{
index
+
1
}}
</div>
<div
class=
"box1-item-right"
>
<div
class=
"title"
>
{{
item
.
name
}}
</div>
...
...
@@ -44,13 +53,18 @@
<div
class=
"box1-item-right-footer"
>
<div
class=
"time"
>
{{
item
.
postDate
}}
</div>
<div
class=
"area-box"
>
<div
class=
"area"
:class=
"
{
area1: vall.status === '1',
area2: vall.status === '2',
area3: vall.status === '3',
area4: vall.status === '4',
area5: vall.status === '5'
}" v-for="(vall, idxx) in item.areaList" :key="idxx">
<div
class=
"area"
:class=
"
{
area1: vall.status === '1',
area2: vall.status === '2',
area3: vall.status === '3',
area4: vall.status === '4',
area5: vall.status === '5'
}"
v-for="(vall, idxx) in item.areaList"
:key="idxx"
>
{{
vall
.
industryName
}}
</div>
</div>
...
...
@@ -66,30 +80,49 @@
<div
class=
"icon"
>
<img
src=
"./assets/images/box-header-icon2.png"
alt=
""
/>
</div>
<div
class=
"title"
>
{{
"美对
我
要素打压情况"
}}
</div>
<div
class=
"title"
>
{{
"美对
华
要素打压情况"
}}
</div>
</div>
<div
class=
"box2-main"
>
<div
class=
"inner-box1"
>
<div
class=
"left"
>
<div
class=
"left-main"
>
<el-empty
v-if=
"box2DataList.length === 0"
style=
"padding-top: 80px"
description=
"暂无数据"
:image-size=
"100"
/>
<div
class=
"left-item"
:class=
"
{ leftItemActive: box2LeftActiveIndex === index }"
v-for="(item, index) in box2DataList" :key="index" @click="handleClickBox2Item(index)">
<el-empty
v-if=
"box2DataList.length === 0"
style=
"padding-top: 80px"
description=
"暂无数据1"
:image-size=
"100"
/>
<div
class=
"left-item"
:class=
"
{ leftItemActive: box2LeftActiveIndex === index }"
v-for="(item, index) in box2DataList"
:key="index"
@click="handleClickBox2Item(index)"
>
<div
class=
"id"
>
{{
index
+
1
}}
</div>
<div
class=
"text"
>
{{
item
.
name
}}
</div>
</div>
</div>
<div
class=
"left-footer"
v-if=
"box2DataList.length !== 0"
>
<el-pagination
background
layout=
"prev, pager, next"
:total=
"box2Total"
:page-size=
"box2PageSize"
v-model:current-page=
"box2CurrentPage"
@
current-change=
"handleGetBox2DataList"
size=
"small"
:pager-count=
"4"
/>
<el-pagination
background
layout=
"prev, pager, next"
:total=
"box2Total"
:page-size=
"box2PageSize"
v-model:current-page=
"box2CurrentPage"
@
current-change=
"handleGetBox2DataList"
size=
"small"
:pager-count=
"4"
/>
</div>
</div>
<div
class=
"right"
@
click=
"handleToDecreeDetail(box2DetailInfo)"
>
<el-empty
v-if=
"box2DataList.length === 0 || !isShowBox2Info"
style=
"padding-top: 80px"
description=
"暂无数据"
:image-size=
"100"
/>
<el-empty
v-if=
"box2DataList.length === 0 || !isShowBox2Info"
style=
"padding-top: 80px"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
>
<div
class=
"title"
>
{{
box2DetailInfo
?.
name
}}
</div>
<div
class=
"tag-box"
>
...
...
@@ -99,13 +132,18 @@
</div>
<div
class=
"content"
>
{{
box2DetailInfo
?.
describe
}}
</div>
<div
class=
"area-box"
>
<div
class=
"area"
:class=
"
{
area1: item.status === '1',
area2: item.status === '2',
area3: item.status === '3',
area4: item.status === '4',
area5: item.status === '5'
}" v-for="(item, index) in box2DetailInfo.areaList" :key="index">
<div
class=
"area"
:class=
"
{
area1: item.status === '1',
area2: item.status === '2',
area3: item.status === '3',
area4: item.status === '4',
area5: item.status === '5'
}"
v-for="(item, index) in box2DetailInfo.areaList"
:key="index"
>
{{
item
.
industryName
}}
</div>
</div>
...
...
@@ -132,23 +170,43 @@
<
div
class
=
"inner-box1"
>
<
div
class
=
"left"
>
<
div
class
=
"left-main"
>
<
el
-
empty
v
-
if
=
"box3DataList.length === 0"
style
=
"padding-top: 80px"
description
=
"暂无数据"
:
image
-
size
=
"100"
/>
<
div
class
=
"left-item"
:
class
=
"{ leftItemActive: box3LeftActiveIndex === index
}
"
v
-
for
=
"(item, index) in box3DataList"
:
key
=
"index"
@
click
=
"handleClickBox3Item(index)"
>
<
el
-
empty
v
-
if
=
"box3DataList.length === 0"
style
=
"padding-top: 80px"
description
=
"暂无数据"
:
image
-
size
=
"100"
/>
<
div
class
=
"left-item"
:
class
=
"{ leftItemActive: box3LeftActiveIndex === index
}
"
v
-
for
=
"(item, index) in box3DataList"
:
key
=
"index"
@
click
=
"handleClickBox3Item(index)"
>
<
div
class
=
"id"
>
{{
index
+
1
}}
<
/div
>
<
div
class
=
"text"
>
{{
item
.
name
}}
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"left-footer"
v
-
if
=
"box3DataList.length"
>
<
el
-
pagination
background
layout
=
"prev, pager, next"
:
total
=
"box3Total"
:
page
-
size
=
"box3PageSize"
v
-
model
:
current
-
page
=
"box3CurrentPage"
@
current
-
change
=
"handleGetBox3DataList"
size
=
"small"
:
pager
-
count
=
"4"
/>
<
el
-
pagination
background
layout
=
"prev, pager, next"
:
total
=
"box3Total"
:
page
-
size
=
"box3PageSize"
v
-
model
:
current
-
page
=
"box3CurrentPage"
@
current
-
change
=
"handleGetBox3DataList"
size
=
"small"
:
pager
-
count
=
"4"
/>
<
/div
>
<
/div
>
<
div
class
=
"right"
@
click
=
"handleToDecreeDetail(box3DetailInfo)"
>
<
el
-
empty
v
-
if
=
"box3DataList.length === 0 || !isShowBox3Info"
style
=
"padding-top: 80px"
description
=
"暂无数据"
:
image
-
size
=
"100"
/>
<
el
-
empty
v
-
if
=
"box3DataList.length === 0 || !isShowBox3Info"
style
=
"padding-top: 80px"
description
=
"暂无数据"
:
image
-
size
=
"100"
/>
<
div
v
-
else
>
<
div
class
=
"title"
>
{{
box3DetailInfo
?.
name
}}
<
/div
>
<
div
class
=
"tag-box"
>
...
...
@@ -158,13 +216,18 @@
<
/div
>
<
div
class
=
"content"
>
{{
box3DetailInfo
?.
describe
}}
<
/div
>
<
div
class
=
"area-box"
>
<
div
class
=
"area"
:
class
=
"{
area1: item.status === '1',
area2: item.status === '2',
area3: item.status === '3',
area4: item.status === '4',
area5: item.status === '5'
}
"
v
-
for
=
"(item, index) in box3DetailInfo?.areaList"
:
key
=
"index"
>
<
div
class
=
"area"
:
class
=
"{
area1: item.status === '1',
area2: item.status === '2',
area3: item.status === '3',
area4: item.status === '4',
area5: item.status === '5'
}
"
v
-
for
=
"(item, index) in box3DetailInfo?.areaList"
:
key
=
"index"
>
{{
item
.
industryName
}}
<
/div
>
<
/div
>
...
...
@@ -175,8 +238,12 @@
<
/div
>
<
/div
>
<
div
class
=
"inner-box2"
>
<
el
-
empty
v
-
if
=
"box3ChartData.length === 0"
style
=
"padding-top: 80px"
description
=
"暂无数据"
:
image
-
size
=
"100"
/>
<
el
-
empty
v
-
if
=
"box3ChartData.length === 0"
style
=
"padding-top: 80px"
description
=
"暂无数据"
:
image
-
size
=
"100"
/>
<
div
class
=
"chart-header"
>
{{
"关键词云"
}}
<
/div
>
<
div
class
=
"box3Chart"
id
=
"box3Chart"
><
/div
>
<
/div
>
...
...
@@ -204,9 +271,8 @@ import {
const
activeDate
=
inject
(
"activeDate"
);
const
isShowBox2Info
=
ref
(
true
)
const
isShowBox3Info
=
ref
(
true
)
const
isShowBox2Info
=
ref
(
true
);
const
isShowBox3Info
=
ref
(
true
);
const
getCalculatedDate
=
type
=>
{
const
now
=
new
Date
();
...
...
@@ -256,7 +322,7 @@ const handleGetHeaderList = async () => {
if
(
res
.
code
===
200
&&
res
.
data
)
{
headerList
.
value
=
res
.
data
;
}
}
catch
(
error
)
{
}
}
catch
(
error
)
{
}
}
;
// 最新动态
...
...
@@ -283,7 +349,7 @@ const handleGetBox1Data = async () => {
if
(
res
.
code
===
200
&&
res
.
data
)
{
box1DataList
.
value
=
res
.
data
;
}
}
catch
(
error
)
{
}
}
catch
(
error
)
{
}
}
;
const
box2DataList
=
ref
([]);
...
...
@@ -304,10 +370,10 @@ const handleGetOrderInfo = async id => {
if
(
res
.
code
===
200
&&
res
.
data
)
{
box2DetailInfo
.
value
=
res
.
data
;
}
else
{
isShowBox2Info
.
value
=
false
isShowBox2Info
.
value
=
false
;
}
}
catch
(
error
)
{
isShowBox2Info
.
value
=
false
isShowBox2Info
.
value
=
false
;
}
}
;
...
...
@@ -326,7 +392,7 @@ const handleGetBox2DataList = async () => {
box2Total
.
value
=
res
.
data
.
totalElements
;
handleGetOrderInfo
(
box2DataList
.
value
[
box2LeftActiveIndex
.
value
].
id
);
}
}
catch
(
error
)
{
}
}
catch
(
error
)
{
}
}
;
const
handleClickBox2Item
=
index
=>
{
...
...
@@ -351,7 +417,7 @@ const handleGetBox2ChartData = async () => {
}
;
}
);
}
}
catch
(
error
)
{
}
}
catch
(
error
)
{
}
}
;
const
handleBox2Chart
=
async
()
=>
{
await
handleGetBox2ChartData
();
...
...
@@ -378,10 +444,10 @@ const handleGetOrderInfo1 = async id => {
if
(
res
.
code
===
200
&&
res
.
data
)
{
box3DetailInfo
.
value
=
res
.
data
;
}
else
{
isShowBox3Info
.
value
=
false
isShowBox3Info
.
value
=
false
;
}
}
catch
(
error
)
{
isShowBox3Info
.
value
=
false
isShowBox3Info
.
value
=
false
;
}
}
;
...
...
@@ -407,7 +473,7 @@ const handleGetBox3DataList = async () => {
}
else
{
box3DetailInfo
.
value
=
{
}
;
}
}
catch
(
error
)
{
}
}
catch
(
error
)
{
}
}
;
const
handleClickBox3Item
=
index
=>
{
...
...
@@ -433,7 +499,7 @@ const handleGetBox3ChartData = async () => {
}
;
}
);
}
}
catch
(
error
)
{
}
}
catch
(
error
)
{
}
}
;
const
handleBox3Chart
=
async
()
=>
{
await
handleGetBox3ChartData
();
...
...
src/views/ZMOverView/components/fourSuppress/components/allGovernment/index.vue
浏览文件 @
95f8d886
...
...
@@ -185,8 +185,8 @@
<simple-pagination
v-model:current-page=
"rankCurrentPage"
:page-size=
"
p
ageSize"
:total=
"
r
ankingList.length"
:page-size=
"
rankingP
ageSize"
:total=
"
allR
ankingList.length"
@
page-change=
"handleRankPageChange"
/>
</div>
...
...
@@ -426,6 +426,7 @@ const getUSGovernmentSanctionHistoryData = async () => {
const
loadingJointRank
=
ref
(
false
);
const
getUSGovernmentJointSanctionRankData
=
async
()
=>
{
loadingJointRank
.
value
=
true
;
const
params
=
{};
try
{
const
res
=
await
getUSGovernmentJointSanctionRank
();
if
(
res
.
code
===
200
&&
res
.
data
)
{
...
...
@@ -494,8 +495,8 @@ const updateDynamicListByPage = () => {
};
const
updateRankListByPage
=
()
=>
{
const
start
=
(
rankCurrentPage
.
value
-
1
)
*
p
ageSize
.
value
;
const
end
=
start
+
p
ageSize
.
value
;
const
start
=
(
rankCurrentPage
.
value
-
1
)
*
rankingP
ageSize
.
value
;
const
end
=
start
+
rankingP
ageSize
.
value
;
rankingList
.
value
=
allRankingList
.
value
.
slice
(
start
,
end
);
};
// 点击科技要闻-跳转详情页
...
...
@@ -792,31 +793,7 @@ const fieldOptions = ref([
{
label
:
"其他"
,
value
:
"99"
}
]);
const
methodOptions
=
ref
([
// { label: "全部制裁手段", value: "" },
// { label: "法案", value: "-1" },
// { label: "政令", value: "-2" },
// { label: "实体清单", value: "1" },
// { label: "特别国民指定清单", value: "2" },
// { label: "涉军企业", value: "3" },
// { label: "行业制裁识别清单", value: "4" },
// { label: "无法核实清单", value: "5" },
// { label: "军事最终用户清单", value: "6" },
// { label: "非SDN中国军工企业名单", value: "7" },
// { label: "拒绝往来人员清单", value: "8" },
// { label: "军事最终用途与最终用户规则", value: "9" },
// { label: "欧盟合并制裁清单", value: "10" },
// { label: "英国制裁清单", value: "11" },
// { label: "加拿大合并自主制裁清单", value: "12" },
// { label: "商业管制清单", value: "13" }
// { label: "232调查", value: "14" },
// { label: "Capta List (CAP) - Treasury Department", value: "15" },
// { label: "ITAR Debarred (DTC) - State Department", value: "16" },
// { label: "Nonproliferation Sanctions (ISN) - State Department", value: "17" },
// { label: "Non-SDN Menu-Based Sanctions List (NS-MBS List) - Treasury Department", value: "18" },
// { label: "Palestinian Legislative Council List (PLC) - Treasury Department", value: "19" },
// { label: "经验证最终用户清单", value: "20" }
]);
const
methodOptions
=
ref
([]);
const
handleGetSanList
=
async
()
=>
{
const
params
=
{
...
...
@@ -832,16 +809,17 @@ const handleGetSanList = async () => {
value
:
item
.
id
};
});
methodValue
.
value
=
""
;
}
}
catch
(
error
)
{}
};
watch
(
()
=>
methodValue
.
value
,
val
=>
{
getDepartmentListData
();
}
);
//
watch(
//
() => methodValue.value,
//
val => {
//
getDepartmentListData();
//
}
//
);
watch
(
()
=>
deptValue
.
value
,
...
...
@@ -854,6 +832,7 @@ const allDynamicData = ref([]);
const
dynamicList
=
ref
([]);
const
newsCurrentPage
=
ref
(
1
);
const
pageSize
=
ref
(
5
);
// 每页显示 5 条
const
rankingPageSize
=
ref
(
10
);
const
handleNewsPageChange
=
page
=>
{
newsCurrentPage
.
value
=
page
;
...
...
@@ -1669,7 +1648,7 @@ const prev = () => {
// border-radius: 10px;
// border: 1px solid rgb(234, 236, 238);
border-bottom
:
1px
solid
rgb
(
234
,
236
,
238
);
padding
:
1
2
px
24px
;
padding
:
1
0
px
24px
;
margin-bottom
:
12px
;
box-sizing
:
border-box
;
...
...
src/views/ZMOverView/components/fourSuppress/components/allUnion/index.vue
浏览文件 @
95f8d886
...
...
@@ -6,10 +6,16 @@
<img
src=
"./assets/leftbtn.png"
alt
class=
"left-btn"
@
click=
"prev"
:class=
"
{ disabled: startIndex === 0 }" />
<div
class=
"content"
>
<div
class=
"carousel-container"
:style=
"
{ transform: `translateX(-${startIndex * (307 + 16)}px)` }">
<div
class=
"carousel-item"
v-for=
"
item, index
in carouselList"
:key=
"index"
>
<div
class=
"carousel-item"
v-for=
"
(item, index)
in carouselList"
:key=
"index"
>
<div
class=
"item-top"
>
<div
class=
"top-img"
>
<img
:src=
"ele"
:class=
"
{ img1: index !== 0 }" alt v-for="(ele, idx) in item.imageList" :key="idx" />
<img
:src=
"ele"
:class=
"
{ img1: index !== 0 }"
alt
v-for="(ele, idx) in item.imageList"
:key="idx"
/>
</div>
<div
class=
"top-num"
>
{{
item
.
count
}}
次
</div>
</div>
...
...
@@ -20,13 +26,18 @@
:key=
"idxx"
>
{{
ele
.
industryName
}}
</div>
-->
<AreaTag
v-for=
"
ele, idxx
in item.industryList"
:key=
"idxx"
:tagName=
"ele.industryName"
></AreaTag>
<AreaTag
v-for=
"
(ele, idxx)
in item.industryList"
:key=
"idxx"
:tagName=
"ele.industryName"
></AreaTag>
</div>
</div>
</div>
</div>
<img
src=
"./assets/rightbtn.png"
alt
class=
"right-btn"
@
click=
"next"
:class=
"
{ disabled: startIndex >= carouselList.length - 5 }" />
<img
src=
"./assets/rightbtn.png"
alt
class=
"right-btn"
@
click=
"next"
:class=
"
{ disabled: startIndex >= carouselList.length - 5 }"
/>
</div>
<!-- 排华联盟分布 -->
...
...
@@ -48,8 +59,13 @@
<div
class=
"item"
v-for=
"(item, index) in countList"
:key=
"index"
>
<div
class=
"item-left"
>
<img
:src=
"item.image"
alt
/>
<el-tooltip
effect=
"dark"
:content=
"item.zhName"
popper-class=
"common-prompt-popper"
placement=
"top"
:show-after=
"500"
>
<el-tooltip
effect=
"dark"
:content=
"item.zhName"
popper-class=
"common-prompt-popper"
placement=
"top"
:show-after=
"500"
>
<span>
{{
item
.
zhName
}}
</span>
</el-tooltip>
</div>
...
...
@@ -91,13 +107,18 @@
<
span
>
排华联盟最新动态
<
/span
>
<
/div
>
<
div
class
=
"news-content"
>
<
div
class
=
"item"
v
-
for
=
"
item, index
in newsList"
:
key
=
"index"
>
<
div
class
=
"item"
v
-
for
=
"
(item, index)
in newsList"
:
key
=
"index"
>
<
div
class
=
"item-title"
>
<
img
:
src
=
"item.image || defaultImg"
alt
/>
<
span
@
click
=
"handleClick(item)"
>
{{
item
.
title
}}
<
/span
>
<
/div
>
<
el
-
tooltip
effect
=
"dark"
:
content
=
"item.content"
popper
-
class
=
"common-prompt-popper"
placement
=
"top"
:
show
-
after
=
"500"
>
<
el
-
tooltip
effect
=
"dark"
:
content
=
"item.content"
popper
-
class
=
"common-prompt-popper"
placement
=
"top"
:
show
-
after
=
"500"
>
<
div
class
=
"item-content"
>
{{
item
.
content
}}
<
/div
>
<
/el-tooltip
>
<
div
class
=
"item-bottom"
>
...
...
@@ -106,7 +127,7 @@
:
key
=
"idx"
>
<
span
>
{{
ele
.
industryName
}}
<
/span
>
<
/div> --
>
<
AreaTag
v
-
for
=
"
ele, idx
in item.industryList"
:
key
=
"idx"
:
tagName
=
"ele.industryName"
><
/AreaTag
>
<
AreaTag
v
-
for
=
"
(ele, idx)
in item.industryList"
:
key
=
"idx"
:
tagName
=
"ele.industryName"
><
/AreaTag
>
<
/div
>
<
div
class
=
"bottom-right"
>
{{
getTime
(
item
.
time
)
}}
<
/div
>
<
/div
>
...
...
@@ -123,16 +144,26 @@
<
div
class
=
"item-title"
>
<
div
class
=
"title-left"
>
<
div
class
=
"img-list"
>
<
img
:
src
=
"ele.image || defaultImg"
:
class
=
"{ img1: index !== 0
}
"
@
error
=
"e => (e.target.src = defaultImg)"
alt
v
-
for
=
"(ele, index) in item.countryList"
:
key
=
"index"
/>
<
img
:
src
=
"ele.image || defaultImg"
:
class
=
"{ img1: index !== 0
}
"
@
error
=
"e => (e.target.src = defaultImg)"
alt
v
-
for
=
"(ele, index) in item.countryList"
:
key
=
"index"
/>
<
/div
>
<
div
class
=
"left-content"
>
{{
getContent
(
item
.
countryList
)
}}
<
/div
>
<
/div
>
<
div
class
=
"title-right"
>
{{
item
.
statementList
?.
length
}}
次合作
<
/div
>
<
/div
>
<
div
class
=
"item-content"
>
<
div
class
=
"content-list"
v
-
for
=
"(ele, idx) in item.statementList"
:
key
=
"idx"
@
click
=
"handleClick(ele)"
>
<
div
class
=
"content-list"
v
-
for
=
"(ele, idx) in item.statementList"
:
key
=
"idx"
@
click
=
"handleClick(ele)"
>
<
div
class
=
"list-left"
>
<!--
<
span
>
{{
getName
(
ele
.
industryList
)
}}
<
/span> --
>
<
AreaTag
v
-
if
=
"getName(ele.industryList)"
:
tagName
=
"getName(ele.industryList)"
><
/AreaTag
>
...
...
@@ -945,7 +976,7 @@ const initRightDonut = async () => {
value
:
res
.
data
[
i
].
amount
,
x
:
Math
.
random
()
*
10
,
y
:
Math
.
random
()
*
10
,
symbolSize
:
res
.
data
[
i
].
amount
*
9
,
symbolSize
:
res
.
data
[
i
].
amount
*
9
}
;
// 先判断data中是否包含上述数据
...
...
@@ -985,8 +1016,8 @@ const initRightDonut = async () => {
// text: 'Basic Graph'
}
,
tooltip
:
{
trigger
:
'item'
,
// 针对Graph的节点/边触发(必配,否则弹框不生效)
triggerOn
:
'click'
,
trigger
:
"item"
,
// 针对Graph的节点/边触发(必配,否则弹框不生效)
triggerOn
:
"click"
,
formatter
:
function
(
params
)
{
// params.data 是当前点击节点的完整数据对象
const
{
name
,
value
}
=
params
.
data
;
...
...
@@ -1018,7 +1049,7 @@ const initRightDonut = async () => {
show
:
true
}
,
edgeSymbol
:
[
"circle"
,
""
],
edgeSymbolSize
:
[
4
,
4
0
],
edgeSymbolSize
:
[
4
,
8
0
],
edgeLabel
:
{
fontSize
:
20
}
,
...
...
src/views/bill/billHome/ResourceLibrarySection.vue
浏览文件 @
95f8d886
...
...
@@ -217,9 +217,9 @@ const props = defineProps({
const
tabList
=
ref
([
{
name
:
"国会法案"
,
active
:
true
}
,
{
name
:
"国会议员"
,
active
:
tru
e
}
,
{
name
:
"国会议员"
,
active
:
fals
e
}
,
{
name
:
"议员合作关系"
,
active
:
false
}
,
{
name
:
"委员会"
,
active
:
tru
e
}
{
name
:
"委员会"
,
active
:
fals
e
}
]);
const
activeTabName
=
ref
(
"国会法案"
);
const
handleClickTab
=
tab
=>
{
...
...
src/views/bill/billHome/index.vue
浏览文件 @
95f8d886
...
...
@@ -329,7 +329,7 @@ const handleClickToDetailO = item => {
// 查看更多风险信号
const
handleToMoreRiskSignal
=
()
=>
{
const
route
=
router
.
resolve
(
"/
r
iskSignal"
);
const
route
=
router
.
resolve
(
"/
viewR
iskSignal"
);
window
.
open
(
route
.
href
,
"_blank"
);
};
// 风险信号
...
...
src/views/bill/billLayout/index.vue
浏览文件 @
95f8d886
...
...
@@ -283,7 +283,7 @@ onMounted(() => {
margin
:
0
auto
;
padding-top
:
10px
;
.layout-main-header-left-box
{
width
:
9
00px
;
width
:
26
00px
;
.left-box-top
{
height
:
64px
;
display
:
flex
;
...
...
src/views/bill/introdoction/STimeline.vue
浏览文件 @
95f8d886
...
...
@@ -16,16 +16,16 @@
>
<div
class=
"item-title"
>
{{
item
.
actionTitle
}}
</div>
</el-tooltip>
<div
class=
"right"
>
<
!--
<
div
class=
"right"
>
<div
class=
"risk-tag"
:class=
"item.riskClass"
>
•
{{
item
.
riskText
}}
</div>
<div
class=
"arrow"
>
>
</div>
</div>
</div>
-->
</div>
</div>
<div
class=
"empty"
v-if=
"displayList.length === 0"
>
暂无进展数据
</div>
</div>
<
div
class=
"more"
v-if=
"hasMore"
>
查看更多
<img
:src=
"arrowDown"
/></div
>
<
!--
<div
class=
"more"
v-if=
"hasMore"
>
查看更多
<img
:src=
"arrowDown"
/></div>
--
>
</div>
</
template
>
...
...
src/views/bill/introdoction/index.vue
浏览文件 @
95f8d886
...
...
@@ -145,14 +145,14 @@
<
/div> --
>
<
AnalysisBox
title
=
"法案进展"
:
showAllBtn
=
"false"
>
<
template
#
header
-
btn
>
<
div
class
=
"progress-header-btns"
>
<
!--
<
div
class
=
"progress-header-btns"
>
<
div
class
=
"btn"
:
class
=
"{ btnActive: progressMode === 'latest'
}
"
@
click
=
"handleSwitchProgressMode('latest')"
>
最新进展
<
/div
>
<
div
class
=
"btn"
:
class
=
"{ btnActive: progressMode === 'early'
}
"
@
click
=
"handleSwitchProgressMode('early')"
>
前期进程
<
/div
>
<
/div
>
<
/div>
--
>
<
/template
>
<
div
class
=
"box2-main"
>
<
div
class
=
"box2-main-center"
>
...
...
src/views/companyPages2/component/capitalScale.vue
浏览文件 @
95f8d886
...
...
@@ -8,7 +8,7 @@
<!-- 数值区域 -->
<el-space
:size=
"6"
>
<!-- 数值图标 -->
<div
class=
"item-value-img"
/
>
<div
class=
"item-value-img"
></div
>
<!-- 数值 -->
<div
class=
"item-value"
>
{{
t
.
value
}}
...
...
src/views/companyPages2/component/operatingPages/SanctionsSituation.vue
0 → 100644
浏览文件 @
95f8d886
<
script
setup
>
import
{
ref
,
onMounted
,
onUnmounted
}
from
'vue'
;
import
{
ElSpace
,
ElRadioGroup
,
ElRadio
,
ElRadioButton
}
from
'element-plus'
;
import
*
as
echarts
from
'echarts'
;
import
{
getStudyList
,
getSanctionList
}
from
'@/api/companyPages'
;
import
AnalysisBox
from
'@/components/base/boxBackground/analysisBox.vue'
;
import
AiTipPane
from
'@/components/base/panes/AiTipPane.vue'
// 定义组件属性
const
props
=
defineProps
({
enterpriseInfo
:
{
type
:
Object
,
default
:
{}
}
});
const
studyList
=
ref
([])
const
sanctionList
=
ref
([])
const
studyTypes
=
ref
([])
const
studyType
=
ref
()
const
chartDom
=
ref
()
let
myChart
=
null
onMounted
(
async
()
=>
{
await
intData
()
// await initChart()
})
onUnmounted
(()
=>
myChart
?.
dispose
())
async
function
intData
()
{
const
{
data
}
=
await
getStudyList
(
props
.
enterpriseInfo
.
id
)
studyList
.
value
=
data
??
[]
data
.
forEach
(
t
=>
t
.
time
=
new
Date
(
t
.
year
,
1
,
1
))
studyTypes
.
value
=
[...
new
Set
(
data
.
map
(
t
=>
t
.
type
))]
const
{
data
:
sanctionData
}
=
await
getSanctionList
(
props
.
enterpriseInfo
.
id
)
sanctionList
.
value
=
sanctionData
??
[]
sanctionList
.
value
.
forEach
(
t
=>
t
.
time
=
new
Date
(
t
.
sanctionDate
))
if
(
studyTypes
.
value
.
length
>
0
)
{
studyType
.
value
=
studyTypes
.
value
[
0
]
}
updateCharts
(
studyType
.
value
,
studyList
.
value
,
sanctionList
.
value
)
}
// 辅助函数:获取制裁年份对应的Y值
function
getSanctionYValue
(
sanctionDate
,
filteredList
,
defaultYValue
)
{
const
year
=
sanctionDate
.
getFullYear
()
const
yearData
=
filteredList
.
find
(
d
=>
d
.
year
===
year
)
return
yearData
?
yearData
.
currentValue
:
defaultYValue
}
// 辅助函数:格式化文本内容,实现智能换行(考虑中英文混合)
function
formatContent
(
content
,
maxWidth
=
26
)
{
if
(
!
content
)
return
''
const
lines
=
[]
let
currentLine
=
''
let
currentWidth
=
0
// 中文字符宽度设为2,英文字符宽度设为1
for
(
let
i
=
0
;
i
<
content
.
length
;
i
++
)
{
const
char
=
content
[
i
]
const
charWidth
=
/
[\u
4e00-
\u
9fa5
]
/
.
test
(
char
)
?
2
:
1
if
(
currentWidth
+
charWidth
<=
maxWidth
)
{
currentLine
+=
char
currentWidth
+=
charWidth
}
else
{
lines
.
push
(
currentLine
)
currentLine
=
char
currentWidth
=
charWidth
}
}
if
(
currentLine
)
{
lines
.
push
(
currentLine
)
}
return
lines
.
join
(
'
\
n'
)
}
function
updateCharts
(
type
,
dataStudy
,
dataSanction
)
{
const
filteredList
=
dataStudy
.
filter
(
t
=>
t
.
type
===
type
)
if
(
!
filteredList
.
length
)
return
// 销毁现有图表实例
if
(
myChart
)
{
myChart
.
dispose
()
}
myChart
=
echarts
.
init
(
chartDom
.
value
)
// y轴单位
const
unit
=
filteredList
[
0
].
unit
const
yValue
=
Math
.
max
(...
filteredList
.
map
(
d
=>
d
.
currentValue
))
// 计算x轴范围,扩大活动空间
const
allDates
=
[
...
filteredList
.
map
(
t
=>
t
.
time
),
...
dataSanction
.
map
(
t
=>
t
.
time
)
]
const
minDate
=
new
Date
(
Math
.
min
(...
allDates
))
const
maxDate
=
new
Date
(
Math
.
max
(...
allDates
))
// 向前扩展1年,向后扩展1年
minDate
.
setFullYear
(
minDate
.
getFullYear
()
-
1
)
maxDate
.
setFullYear
(
maxDate
.
getFullYear
()
+
1
)
myChart
.
setOption
({
textStyle
:
{
fontSize
:
14
},
grid
:
{
left
:
60
,
right
:
110
,
},
tooltip
:
{
trigger
:
'axis'
,
position
:
function
(
pt
)
{
return
[
pt
[
0
],
'10%'
];
},
},
dataZoom
:
[
{
type
:
'inside'
,
start
:
0
,
end
:
100
},
{
start
:
0
,
end
:
100
}
],
xAxis
:
{
type
:
'time'
,
boundaryGap
:
false
,
min
:
minDate
,
max
:
maxDate
},
yAxis
:
{
type
:
'value'
,
boundaryGap
:
[
0
,
'100%'
],
// 显示y轴单位在顶部
name
:
unit
,
nameLocation
:
'end'
},
series
:
[
{
type
:
'line'
,
//从上到下填充颜色
areaStyle
:
{
color
:
new
echarts
.
graphic
.
LinearGradient
(
0
,
0
,
0
,
1
,
[
{
offset
:
0
,
color
:
'rgba(128, 181, 255, 0.8)'
},
{
offset
:
1
,
color
:
'rgba(128, 181, 255, 0)'
}
])
},
data
:
filteredList
.
map
(
t
=>
[
t
.
time
,
t
.
currentValue
])
},
{
type
:
'scatter'
,
tooltip
:
{
show
:
false
},
data
:
dataSanction
.
map
(
t
=>
{
const
currentYValue
=
getSanctionYValue
(
t
.
time
,
filteredList
,
yValue
)
+
yValue
/
3
return
[
t
.
time
,
currentYValue
,
t
]
}),
markLine
:
{
lineStyle
:
{
color
:
'#ff4d4f'
,
type
:
'dashed'
,
width
:
1
},
data
:
dataSanction
.
map
(
t
=>
{
const
currentYValue
=
getSanctionYValue
(
t
.
time
,
filteredList
,
yValue
)
+
yValue
/
3
return
[{
coord
:
[
t
.
time
,
0
],
symbol
:
'none'
},
{
coord
:
[
t
.
time
,
currentYValue
],
symbol
:
'none'
,
}]
})
},
coordinateSystem
:
'cartesian2d'
,
symbolSize
:
1
,
label
:
{
show
:
true
,
position
:
'insideBottomLeft'
,
formatter
:
function
(
params
)
{
const
title
=
params
.
data
[
2
].
sanctionDate
;
const
content
=
params
.
data
[
2
].
content
;
const
formattedContent
=
formatContent
(
content
);
return
`{title|
${
title
}
}\n{content|
${
formattedContent
}
}`
;
},
rich
:
{
title
:
{
fontSize
:
16
,
lineHeight
:
22
,
color
:
'#CE4F51'
},
content
:
{
fontSize
:
15
,
fontWeight
:
'bold'
,
width
:
200
,
// 限制宽度
color
:
'#CE4F51'
,
lineHeight
:
22
,
overflow
:
'break'
// 超出宽度自动换行
}
},
backgroundColor
:
'rgba(255, 241, 240, 1)'
,
borderColor
:
'rgba(255, 204, 199, 1)'
,
borderRadius
:
4
,
padding
:
[
8
,
12
],
distance
:
-
1
}
}
],
})
}
function
handleStudyTypesChange
()
{
updateCharts
(
studyType
.
value
,
studyList
.
value
,
sanctionList
.
value
)
}
</
script
>
<
template
>
<analysis-box
title=
"被制裁时间轴"
>
<template
v-slot:header-btn
>
<el-radio-group
v-model=
"studyType"
@
change=
"handleStudyTypesChange"
>
<el-radio-button
v-for=
"item in studyTypes"
:key=
"item"
:label=
"item"
>
{{
item
}}
</el-radio-button>
</el-radio-group>
</
template
>
<div
class=
"flex-display content-box"
>
<div
ref=
"chartDom"
class=
"chart-container"
></div>
<ai-tip-pane>
123
</ai-tip-pane>
</div>
</analysis-box>
</template>
<
style
lang=
"scss"
scoped
>
.content-box
{
padding
:
10px
;
gap
:
10px
;
flex-direction
:
column
;
}
.chart-container
{
height
:
500px
;
width
:
100%
;
}
</
style
>
\ No newline at end of file
src/views/companyPages2/component/operatingPages/index.vue
浏览文件 @
95f8d886
<
script
setup
lang=
"ts"
>
import
'@/styles/tabs.scss'
import
{
ElTabPane
,
ElTabs
}
from
'element-plus'
;
import
SanctionsSituation
from
'./SanctionsSituation.vue'
;
// 定义组件属性
const
props
=
defineProps
({
enterpriseInfo
:
{
type
:
Object
,
default
:
{}
}
});
</
script
>
<
template
>
<el-tabs
tabPosition=
"left"
class=
"disinheritance tabs-nav-no-wrap left-float-nav-tabs"
>
<el-tab-pane
label=
"企业规模"
></el-tab-pane>
<el-tab-pane
label=
"市值变化"
></el-tab-pane>
<el-tab-pane
label=
"研发投入"
></el-tab-pane>
<el-tab-pane
label=
"市场占比"
></el-tab-pane>
</el-tabs>
<div
style=
"overflow: visible;"
>
<el-tabs
tabPosition=
"left"
class=
"disinheritance tabs-nav-no-wrap left-float-nav-tabs"
>
<el-tab-pane
label=
"企业规模"
>
<sanctions-situation
:enterprise-info=
"enterpriseInfo"
></sanctions-situation>
</el-tab-pane>
<!--
<el-tab-pane
label=
"市值变化"
></el-tab-pane>
<el-tab-pane
label=
"研发投入"
></el-tab-pane>
<el-tab-pane
label=
"市场占比"
></el-tab-pane>
-->
</el-tabs>
</div>
</
template
>
\ No newline at end of file
src/views/companyPages2/index.vue
浏览文件 @
95f8d886
...
...
@@ -4,7 +4,7 @@
</div>
<el-scrollbar>
<div
class=
"common-page"
>
<el-space
wrap
:size=
"16"
>
<el-space
wrap
:size=
"16"
fill
>
<title-pane
:enterprise-info=
"enterpriseInfo"
></title-pane>
<el-tabs
stretch
class=
"tabs-header-as-card tabs-nav-no-wrap tabs-bar-as-btn"
>
<el-tab-pane
label=
"企业详情"
>
...
...
@@ -14,7 +14,7 @@
</div>
</el-tab-pane>
<el-tab-pane
lazy
label=
"经营情况"
>
<operating-pages
/>
<operating-pages
:enterprise-info=
"enterpriseInfo"
/>
</el-tab-pane>
<el-tab-pane
lazy
label=
"供应链 / 股权"
>
<div
class=
"flex-display"
>
...
...
src/views/coopRestriction/components/dataNew/index.vue
浏览文件 @
95f8d886
...
...
@@ -207,7 +207,7 @@ const handleToRiskDetail = (item) => {
// 查看更多风险信号
const
handleToMoreRiskSignal
=
()
=>
{
const
route
=
router
.
resolve
(
"/
r
iskSignal"
);
const
route
=
router
.
resolve
(
"/
vieR
iskSignal"
);
window
.
open
(
route
.
href
,
"_blank"
);
};
...
...
src/views/coopRestriction/index.vue
浏览文件 @
95f8d886
...
...
@@ -26,7 +26,7 @@
</div>
<!-- 资讯要问 -->
<div
class=
"ask"
id=
"position2"
>
<com-title
title=
"
咨询
要闻"
/>
<com-title
title=
"
资讯
要闻"
/>
<div
class=
"ask-main"
>
<askPage
/>
</div>
...
...
src/views/decree/decreeHome/index.vue
浏览文件 @
95f8d886
...
...
@@ -534,7 +534,7 @@ handleGetDepartmentList();
// 查看更多风险信号
const
handleToMoreRiskSignal
=
()
=>
{
const
route
=
router
.
resolve
(
"/
r
iskSignal"
);
const
route
=
router
.
resolve
(
"/
viewR
iskSignal"
);
window
.
open
(
route
.
href
,
"_blank"
);
};
...
...
src/views/exportControl/index.vue
浏览文件 @
95f8d886
...
...
@@ -50,12 +50,25 @@
<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=
"实体清单"
/>
<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=
"次"
:color=
"infoListColor[index]"
@
click=
"handleToEntityListNoId(item)"
/>
<InfoCard
v-for=
"(item, index) in infoList"
:key=
"item.id"
:title=
"item.nameZh"
:subtitle=
"item.nameAbbr"
:description=
"item.description"
:quantity=
"item.postCount"
unit=
"次"
:color=
"infoListColor[index]"
@
click=
"handleToEntityListNoId(item)"
/>
</div>
</div>
...
...
@@ -81,8 +94,15 @@
<img
src=
"./assets/images/box1-right.png"
alt=
""
/>
</div>
</div>
<el-carousel
ref=
"carouselRef"
height=
"370px"
:autoplay=
"true"
:interval=
"3000"
arrow=
"never"
indicator-position=
"none"
@
change=
"handleCarouselChange"
>
<el-carousel
ref=
"carouselRef"
height=
"370px"
:autoplay=
"true"
: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"
>
...
...
@@ -92,16 +112,21 @@
<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>
<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>
<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>
<div
class=
"box1-top-content-item-tags"
v-for=
"(domainItem, index) in item.domains"
:key=
"index"
>
<div
class=
"box1-top-content-item-tags"
v-for=
"(domainItem, index) in item.domains"
:key=
"index"
>
<el-tag
:type=
"getTagType(domainItem)"
>
{{
domainItem
}}
</el-tag>
</div>
</div>
...
...
@@ -110,10 +135,18 @@
<div
class=
"box1-bottom"
>
<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
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
.
entityNameZh
||
ett
.
enName
)?.
match
(
...
...
@@ -186,10 +219,14 @@
</div>
</template>
</custom-container> -->
<RiskSignal
:list=
"warningList"
@
item-click=
"handleToRiskSignalDetail"
@
more-click=
"handleToMoreRiskSignal"
riskLevel=
"signalLevel"
postDate=
"signalTime"
name=
"signalTitle"
/>
<RiskSignal
:list=
"warningList"
@
item-click=
"handleToRiskSignalDetail"
@
more-click=
"handleToMoreRiskSignal"
riskLevel=
"signalLevel"
postDate=
"signalTime"
name=
"signalTitle"
/>
</el-col>
</el-row>
...
...
@@ -212,12 +249,19 @@
</custom-container>
</el-col> -->
<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"
/>
<NewsList
:newsList=
"newsList"
@
item-click=
"handleNewsInfoClick"
@
more-click=
"handleToMoreNews"
content=
"newsContent"
/>
<MessageBubble
:messageList=
"socialMediaList"
@
person-click=
"handlePerClick"
imageUrl=
"avatar"
@
more-click=
"handleToSocialDetail"
/>
<!-- <custom-container title="社交媒体" :titleIcon="dialogIcon" height="450px">
<template #default>
<div class="dialog-list">
...
...
@@ -227,12 +271,8 @@
</div>
</template>
</custom-container> -->
</div>
<el-row
:gutter=
"20"
style=
"width: 1600px; margin: 0 auto; height: 528px; margin-top: 64px"
>
<CustomTitle
id=
"position3"
title=
"数据总览"
/>
<el-col
:span=
"24"
>
...
...
@@ -247,14 +287,19 @@
<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)"
/>
<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=
"280"
align=
"center"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
>
<div
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
>
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
}}
</el-tag>
...
...
@@ -271,14 +316,19 @@
<
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)"
/>
<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=
"280"
align=
"center"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
>
<div
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
>
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
}}
</el-tag>
...
...
@@ -295,17 +345,21 @@
<
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)"
/>
<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>
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
}}
</el-tag>
</div>
</
template
>
</el-table-column>
...
...
@@ -334,7 +388,8 @@
<div
style=
"display: flex; align-items: center; gap: 16px"
>
<el-checkbox
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-option
v-for=
"item in infoList"
:key=
"item.id"
:label=
"item.nameZh"
:value=
"item.id"
/>
</el-select>
</div>
</
template
>
...
...
@@ -348,9 +403,13 @@
<el-row
:gutter=
"20"
style=
"width: 1600px; margin: 0 auto; margin-top: 39px"
>
<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"
<div
v-for=
"tab in resourceTabs"
:key=
"tab.value"
class=
"resource-tab-item"
:class=
"{ active: activeResourceTab === tab.value, disabled: tab.disabled }"
@
click=
"handleResourceTabClick(tab)"
>
@
click=
"handleResourceTabClick(tab)"
>
{{ tab.label }}
</div>
</div>
...
...
@@ -360,18 +419,29 @@
<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"
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
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-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"
>
<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>
...
...
@@ -379,8 +449,12 @@
</div>
</div>
</div>
<div
class=
"box4-footer"
:style=
"
{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }">
<el-button
type=
"primary"
link
@
click=
"handleGetMore"
>
查看更多
<div
class=
"box4-footer"
:style=
"
{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }"
>
<el-button
type=
"primary"
link
@
click=
"handleGetMore"
>
查看更多
<el-icon>
<DArrowRight
/>
</el-icon>
...
...
@@ -397,8 +471,15 @@
</
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
: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=
"index"
label=
"序号"
width=
"80"
align=
"center"
>
<template
#
default=
"scope"
>
{{
scope
.
$index
+
1
+
(
currentPage
-
1
)
*
pageSize
}}
...
...
@@ -408,8 +489,12 @@
<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>
<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
(
...
...
@@ -417,7 +502,8 @@
)?.[
0
]
}}
</div>
<CommonPrompt
:content=
"scope.row.name"
style=
"flex: 1; overflow: hidden"
/>
<CommonPrompt
:content=
"scope.row.name"
style=
"flex: 1; overflow: hidden"
/>
</div>
</
template
>
</el-table-column>
...
...
@@ -425,9 +511,10 @@
<el-table-column
prop=
"domains"
label=
"涉及领域"
min-width=
"150"
>
<
template
#
default=
"scope"
>
<div
class=
"domain-tags"
>
<el-tag
v-for=
"tag in scope.row.domains"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
}}
</el-tag>
<el-tag
v-for=
"tag in scope.row.domains"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
}}
</el-tag>
</div>
</
template
>
</el-table-column>
...
...
@@ -460,13 +547,19 @@
<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' : ''
]"
>
<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)"
>
<div
style=
"width: 50px; color: #409eff; cursor: pointer"
@
click=
"handleOrgClick(scope.row)"
>
{{
scope
.
row
.
ruleOrgCount
}}
家>
</div>
</div>
...
...
@@ -478,8 +571,15 @@
<!-- <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"
/>
<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>
...
...
@@ -500,9 +600,10 @@
<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>
<el-checkbox
v-for=
"item in techOptions"
:key=
"item.value"
:label=
"item.value"
>
{{
item
.
label
}}
</el-checkbox>
</div>
</el-checkbox-group>
</div>
...
...
@@ -533,10 +634,12 @@
</div>
<img
:src=
"item.orgLogoUrl || comTitle"
alt=
""
/>
<div
class=
"main"
>
<div
class=
"main-title"
@
click=
"handleTitleClick(item)"
>
{{
item
.
title
}}
</div>
<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
v-for=
"tag in item.tags"
:key=
"tag"
class=
"tag-item"
>
{{
tag
}}
</div>
</div>
<div
:class=
"
{ 'count-tag': item.countTag }">
{{
item
.
countTag
}}
</div>
...
...
@@ -545,8 +648,14 @@
</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"
/>
<el-pagination
v-model:current-page=
"currentPageAll"
:page-size=
"pageSizeAll"
:total=
"totalAll"
layout=
"prev, pager, next"
background
@
current-change=
"handlePageChangeAll"
/>
</div>
</div>
</div>
...
...
@@ -581,8 +690,12 @@
</div>
</template>
</el-dialog> -->
<RuleSubsidiaryDialog
v-model=
"dialogVisible"
:company-name=
"currentRuleCompany"
:total-count=
"currentRuleCount"
:data-list=
"currentOrgList"
/>
<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"
>
...
...
@@ -834,7 +947,7 @@ onMounted(async () => {
]);
// 交换第二个和第三个元素
[
dataCount
[
1
],
dataCount
[
2
]]
=
[
dataCount
[
2
],
dataCount
[
1
]];
infoList
.
value
=
dataCount
;
infoList
.
value
=
dataCount
.
slice
(
0
,
2
)
;
const
entityList
=
_
.
map
(
entitiesDataInfo
?.
sanEntities
??
[],
({
entityNameZh
,
entityName
})
=>
{
return
{
name
:
entityNameZh
,
enName
:
entityName
};
...
...
@@ -1254,7 +1367,7 @@ const fetchSanctionList = async () => {
});
totalAll
.
value
=
res
.
totalElements
;
}
}
catch
(
error
)
{
}
}
catch
(
error
)
{}
};
const
handlePageChangeAll
=
val
=>
{
...
...
@@ -1497,9 +1610,9 @@ const handlePerClick = item => {
// 添加格式化时间的方法
const
formatTime
=
timeStr
=>
{
// 空值兜底,避免报错
if
(
!
timeStr
)
return
'暂无时间'
;
if
(
!
timeStr
)
return
"暂无时间"
;
// 核心:替换T为空格
return
timeStr
.
replace
(
'T'
,
' '
);
return
timeStr
.
replace
(
"T"
,
" "
);
};
const
warningList
=
ref
([]);
...
...
@@ -1526,7 +1639,7 @@ const handleGetHylyList = async () => {
hylymc
:
"全部分类"
};
categoryList
.
value
=
[
obj
,
...
categoryList
.
value
];
}
catch
(
error
)
{
}
}
catch
(
error
)
{}
};
const
chart1Data
=
ref
({
...
...
@@ -1570,7 +1683,7 @@ const handleSanc = item => {
// 查看更多风险信号
const
handleToMoreRiskSignal
=
()
=>
{
const
route
=
router
.
resolve
(
"/
r
iskSignal"
);
const
route
=
router
.
resolve
(
"/
viewR
iskSignal"
);
window
.
open
(
route
.
href
,
"_blank"
);
};
...
...
@@ -2017,7 +2130,6 @@ const handleMediaClick = item => {
}
.box3-content
{
// flex: 1;
.el-progress--line
{
width
:
82px
;
...
...
@@ -3413,7 +3525,6 @@ const handleMediaClick = item => {
.center-center-news
{
flex-shrink
:
0
;
}
.boxs4
{
...
...
src/views/exportControl/v2.0SingleSanction/components/deepMining/components/RelationGraph.vue
0 → 100644
浏览文件 @
95f8d886
<
template
>
<div
class=
"relation-graph-wrapper"
>
<div
class=
"graph-controls"
>
<div
v-for=
"item in controlBtns"
:key=
"item.type"
:class=
"['control-btn',
{ 'control-btn-active': currentLayoutType === item.type }]"
@click="handleClickControlBtn(item.type)"
>
<img
:src=
"item.icon"
alt=
""
/>
</div>
</div>
<div
ref=
"containerRef"
class=
"graph-container"
></div>
<div
v-if=
"selectedNode"
class=
"node-popup"
>
<div
class=
"popup-header"
>
<img
:src=
"selectedNode.image || defaultIcon"
alt=
""
class=
"popup-icon"
/>
<div
class=
"popup-title"
>
{{
selectedNode
.
name
}}
</div>
<el-icon
class=
"close-icon"
@
click=
"selectedNode = null"
>
<Close
/>
</el-icon>
</div>
<div
class=
"popup-body"
>
<div
v-if=
"selectedNode.isSanctioned"
class=
"tag-row"
>
<span
class=
"red-dot"
></span>
<span
class=
"red-text"
>
被制裁实体
</span>
</div>
<p
class=
"desc"
>
{{
selectedNode
.
description
||
'暂无描述'
}}
</p>
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
onUnmounted
,
watch
,
nextTick
}
from
'vue'
import
G6
from
'@antv/g6'
import
{
Close
}
from
'@element-plus/icons-vue'
import
echartsIcon01
from
'../assets/echartsicon01.png'
import
echartsIcon02
from
'../assets/echartsicon02.png'
import
echartsIcon03
from
'../assets/echartsicon03.png'
import
defaultIcon
from
'../assets/echartsicon03.png'
const
props
=
defineProps
({
graphData
:
{
type
:
Object
,
default
:
()
=>
({
nodes
:
[],
links
:
[]
})
},
treeData
:
{
type
:
Object
,
default
:
()
=>
null
},
controlActive
:
{
type
:
Number
,
default
:
1
}
})
const
emit
=
defineEmits
([
'nodeClick'
,
'layoutChange'
])
const
containerRef
=
ref
(
null
)
const
graphInstance
=
ref
(
null
)
const
currentLayoutType
=
ref
(
1
)
const
selectedNode
=
ref
(
null
)
const
controlBtns
=
[
{
type
:
1
,
icon
:
echartsIcon01
,
name
:
'力导向布局'
},
{
type
:
2
,
icon
:
echartsIcon02
,
name
:
'树布局'
},
{
type
:
3
,
icon
:
echartsIcon03
,
name
:
'环状布局'
}
]
const
initGraph
=
(
layoutType
=
1
)
=>
{
if
(
!
containerRef
.
value
)
return
destroyGraph
()
nextTick
(()
=>
{
const
container
=
containerRef
.
value
const
width
=
container
.
offsetWidth
||
800
const
height
=
container
.
offsetHeight
||
600
if
(
layoutType
===
2
)
{
initTreeGraph
(
width
,
height
)
}
else
if
(
layoutType
===
3
)
{
initCircularGraph
(
width
,
height
)
}
else
{
initNormalGraph
(
layoutType
,
width
,
height
)
}
})
}
const
initNormalGraph
=
(
layoutType
,
width
,
height
)
=>
{
const
data
=
processGraphData
(
props
.
graphData
)
if
(
!
data
.
nodes
||
data
.
nodes
.
length
===
0
)
return
const
layout
=
{
type
:
'force'
,
center
:
[
width
/
2
,
height
/
2
],
preventOverlap
:
true
,
nodeSpacing
:
80
,
linkDistance
:
250
,
nodeStrength
:
-
800
,
edgeStrength
:
0.1
,
collideStrength
:
0.8
,
alphaDecay
:
0.01
,
alphaMin
:
0.001
}
graphInstance
.
value
=
new
G6
.
Graph
({
container
:
containerRef
.
value
,
width
,
height
,
fitView
:
true
,
fitViewPadding
:
100
,
fitCenter
:
true
,
animate
:
true
,
animateCfg
:
{
duration
:
300
,
easing
:
'easeLinear'
},
minZoom
:
0.1
,
maxZoom
:
10
,
modes
:
{
default
:
[
'drag-canvas'
,
'zoom-canvas'
,
'drag-node'
,
{
type
:
'activate-relations'
,
trigger
:
'mouseenter'
,
resetSelected
:
true
}
]
},
layout
,
defaultNode
:
{
type
:
'image'
,
size
:
40
,
clipCfg
:
{
show
:
true
,
type
:
'circle'
,
r
:
20
},
labelCfg
:
{
position
:
'bottom'
,
offset
:
10
,
style
:
{
fill
:
'#333'
,
fontSize
:
11
,
fontFamily
:
'Microsoft YaHei'
,
textAlign
:
'center'
,
background
:
{
fill
:
'rgba(255, 255, 255, 0.95)'
,
padding
:
[
4
,
6
,
4
,
6
],
radius
:
4
}
}
}
},
defaultEdge
:
{
type
:
'quadratic'
,
style
:
{
stroke
:
'#5B8FF9'
,
lineWidth
:
3
,
opacity
:
0.9
,
endArrow
:
{
path
:
'M 0,0 L 12,6 L 12,-6 Z'
,
fill
:
'#5B8FF9'
}
},
labelCfg
:
{
autoRotate
:
true
,
style
:
{
fill
:
'#333'
,
fontSize
:
10
,
fontFamily
:
'Microsoft YaHei'
,
background
:
{
fill
:
'#fff'
,
padding
:
[
2
,
4
,
2
,
4
],
radius
:
2
}
}
}
},
nodeStateStyles
:
{
active
:
{
shadowColor
:
'#1459BB'
,
shadowBlur
:
15
,
stroke
:
'#1459BB'
,
lineWidth
:
3
},
inactive
:
{
opacity
:
0.3
}
},
edgeStateStyles
:
{
active
:
{
stroke
:
'#1459BB'
,
lineWidth
:
4
},
inactive
:
{
opacity
:
0.15
}
}
})
graphInstance
.
value
.
data
(
data
)
graphInstance
.
value
.
render
()
bindGraphEvents
()
}
const
initCircularGraph
=
(
width
,
height
)
=>
{
const
data
=
processGraphData
(
props
.
graphData
)
if
(
!
data
.
nodes
||
data
.
nodes
.
length
===
0
)
return
const
centerX
=
width
/
2
const
centerY
=
height
/
2
const
radius
=
Math
.
min
(
width
,
height
)
/
2
-
120
const
otherNodes
=
data
.
nodes
.
filter
(
n
=>
!
n
.
isCenter
)
const
nodeCount
=
otherNodes
.
length
otherNodes
.
forEach
((
node
,
index
)
=>
{
const
angle
=
(
2
*
Math
.
PI
*
index
)
/
nodeCount
-
Math
.
PI
/
2
node
.
x
=
centerX
+
radius
*
Math
.
cos
(
angle
)
node
.
y
=
centerY
+
radius
*
Math
.
sin
(
angle
)
})
const
centerNode
=
data
.
nodes
.
find
(
n
=>
n
.
isCenter
)
if
(
centerNode
)
{
centerNode
.
x
=
centerX
centerNode
.
y
=
centerY
centerNode
.
fx
=
centerX
centerNode
.
fy
=
centerY
}
graphInstance
.
value
=
new
G6
.
Graph
({
container
:
containerRef
.
value
,
width
,
height
,
fitView
:
false
,
fitCenter
:
false
,
animate
:
true
,
animateCfg
:
{
duration
:
300
,
easing
:
'easeLinear'
},
minZoom
:
0.1
,
maxZoom
:
10
,
modes
:
{
default
:
[
'drag-canvas'
,
'zoom-canvas'
,
'drag-node'
,
{
type
:
'activate-relations'
,
trigger
:
'mouseenter'
,
resetSelected
:
true
}
]
},
defaultNode
:
{
type
:
'image'
,
size
:
40
,
clipCfg
:
{
show
:
true
,
type
:
'circle'
,
r
:
20
},
labelCfg
:
{
position
:
'bottom'
,
offset
:
10
,
style
:
{
fill
:
'#333'
,
fontSize
:
11
,
fontFamily
:
'Microsoft YaHei'
,
textAlign
:
'center'
,
background
:
{
fill
:
'rgba(255, 255, 255, 0.95)'
,
padding
:
[
4
,
6
,
4
,
6
],
radius
:
4
}
}
}
},
defaultEdge
:
{
type
:
'quadratic'
,
style
:
{
stroke
:
'#5B8FF9'
,
lineWidth
:
3
,
opacity
:
0.9
,
endArrow
:
{
path
:
'M 0,0 L 12,6 L 12,-6 Z'
,
fill
:
'#5B8FF9'
}
},
labelCfg
:
{
autoRotate
:
true
,
style
:
{
fill
:
'#333'
,
fontSize
:
10
,
fontFamily
:
'Microsoft YaHei'
,
background
:
{
fill
:
'#fff'
,
padding
:
[
2
,
4
,
2
,
4
],
radius
:
2
}
}
}
},
nodeStateStyles
:
{
active
:
{
shadowColor
:
'#1459BB'
,
shadowBlur
:
15
,
stroke
:
'#1459BB'
,
lineWidth
:
3
},
inactive
:
{
opacity
:
0.3
}
},
edgeStateStyles
:
{
active
:
{
stroke
:
'#1459BB'
,
lineWidth
:
4
},
inactive
:
{
opacity
:
0.15
}
}
})
graphInstance
.
value
.
data
(
data
)
graphInstance
.
value
.
render
()
bindGraphEvents
()
}
const
initTreeGraph
=
(
width
,
height
)
=>
{
const
treeDataSource
=
convertGraphToTree
(
props
.
graphData
)
if
(
!
treeDataSource
)
return
graphInstance
.
value
=
new
G6
.
TreeGraph
({
container
:
containerRef
.
value
,
width
,
height
,
fitView
:
true
,
fitViewPadding
:
80
,
animate
:
true
,
animateCfg
:
{
duration
:
300
,
easing
:
'easeLinear'
},
minZoom
:
0.1
,
maxZoom
:
10
,
modes
:
{
default
:
[
'drag-canvas'
,
'zoom-canvas'
,
'drag-node'
,
{
type
:
'collapse-expand'
,
onChange
:
function
onChange
(
item
,
collapsed
)
{
const
data
=
item
.
getModel
()
data
.
collapsed
=
collapsed
return
true
}
}
]
},
layout
:
{
type
:
'compactBox'
,
direction
:
'LR'
,
getId
:
function
getId
(
d
)
{
return
d
.
id
},
getHeight
:
function
getHeight
()
{
return
16
},
getWidth
:
function
getWidth
()
{
return
16
},
getVGap
:
function
getVGap
()
{
return
30
},
getHGap
:
function
getHGap
()
{
return
120
}
},
defaultNode
:
{
type
:
'image'
,
size
:
40
,
clipCfg
:
{
show
:
true
,
type
:
'circle'
,
r
:
20
},
labelCfg
:
{
position
:
'right'
,
offset
:
10
,
style
:
{
fill
:
'#333'
,
fontSize
:
11
,
fontFamily
:
'Microsoft YaHei'
,
background
:
{
fill
:
'rgba(255, 255, 255, 0.95)'
,
padding
:
[
4
,
6
,
4
,
6
],
radius
:
4
}
}
}
},
defaultEdge
:
{
type
:
'cubic-horizontal'
,
style
:
{
stroke
:
'#5B8FF9'
,
lineWidth
:
3
}
},
nodeStateStyles
:
{
active
:
{
shadowColor
:
'#1459BB'
,
shadowBlur
:
15
,
stroke
:
'#1459BB'
,
lineWidth
:
3
}
}
})
graphInstance
.
value
.
data
(
treeDataSource
)
graphInstance
.
value
.
render
()
graphInstance
.
value
.
fitView
()
bindGraphEvents
()
}
const
convertGraphToTree
=
(
graphData
)
=>
{
if
(
!
graphData
||
!
graphData
.
nodes
||
graphData
.
nodes
.
length
===
0
)
{
return
null
}
const
nodes
=
graphData
.
nodes
const
links
=
graphData
.
links
||
graphData
.
edges
||
[]
const
centerNode
=
nodes
[
0
]
const
centerId
=
String
(
centerNode
.
id
||
'0'
)
const
childIdSet
=
new
Set
()
const
childrenNodes
=
[]
links
.
forEach
((
link
)
=>
{
const
source
=
String
(
link
.
source
)
const
target
=
String
(
link
.
target
)
if
(
source
===
centerId
&&
!
childIdSet
.
has
(
target
))
{
const
node
=
nodes
.
find
(
n
=>
String
(
n
.
id
)
===
target
)
if
(
node
)
{
childIdSet
.
add
(
target
)
childrenNodes
.
push
({
id
:
target
,
label
:
node
.
name
||
''
,
img
:
node
.
image
||
defaultIcon
,
size
:
node
.
symbolSize
||
40
,
name
:
node
.
name
,
image
:
node
.
image
,
isSanctioned
:
node
.
isSanctioned
})
}
}
else
if
(
target
===
centerId
&&
!
childIdSet
.
has
(
source
))
{
const
node
=
nodes
.
find
(
n
=>
String
(
n
.
id
)
===
source
)
if
(
node
)
{
childIdSet
.
add
(
source
)
childrenNodes
.
push
({
id
:
source
,
label
:
node
.
name
||
''
,
img
:
node
.
image
||
defaultIcon
,
size
:
node
.
symbolSize
||
40
,
name
:
node
.
name
,
image
:
node
.
image
,
isSanctioned
:
node
.
isSanctioned
})
}
}
})
if
(
childrenNodes
.
length
===
0
)
{
nodes
.
slice
(
1
).
forEach
((
node
)
=>
{
const
nodeId
=
String
(
node
.
id
)
if
(
!
childIdSet
.
has
(
nodeId
))
{
childIdSet
.
add
(
nodeId
)
childrenNodes
.
push
({
id
:
nodeId
,
label
:
node
.
name
||
''
,
img
:
node
.
image
||
defaultIcon
,
size
:
node
.
symbolSize
||
40
,
name
:
node
.
name
,
image
:
node
.
image
,
isSanctioned
:
node
.
isSanctioned
})
}
})
}
return
{
id
:
centerId
,
label
:
centerNode
.
name
||
''
,
img
:
centerNode
.
image
||
defaultIcon
,
size
:
centerNode
.
symbolSize
||
60
,
name
:
centerNode
.
name
,
image
:
centerNode
.
image
,
isSanctioned
:
centerNode
.
isSanctioned
,
children
:
childrenNodes
}
}
const
processGraphData
=
(
rawData
)
=>
{
if
(
!
rawData
||
!
rawData
.
nodes
||
rawData
.
nodes
.
length
===
0
)
{
return
{
nodes
:
[],
edges
:
[]
}
}
const
nodeMap
=
new
Map
()
const
nodes
=
[]
rawData
.
nodes
.
forEach
((
node
,
index
)
=>
{
const
nodeId
=
String
(
node
.
id
||
index
)
if
(
nodeMap
.
has
(
nodeId
))
{
return
}
nodeMap
.
set
(
nodeId
,
true
)
const
isCenter
=
index
===
0
const
size
=
node
.
symbolSize
||
(
isCenter
?
60
:
40
)
nodes
.
push
({
id
:
nodeId
,
label
:
node
.
name
||
''
,
img
:
node
.
image
||
defaultIcon
,
size
,
isCenter
,
clipCfg
:
{
show
:
true
,
type
:
'circle'
,
r
:
size
/
2
},
style
:
{
cursor
:
'pointer'
},
labelCfg
:
{
position
:
'bottom'
,
offset
:
12
,
style
:
{
fill
:
isCenter
?
'#1459BB'
:
'#333'
,
fontSize
:
isCenter
?
13
:
11
,
fontWeight
:
isCenter
?
'bold'
:
'normal'
,
fontFamily
:
'Microsoft YaHei'
,
textAlign
:
'center'
}
},
...
node
,
id
:
nodeId
})
})
const
edgeMap
=
new
Map
()
const
edges
=
[]
const
rawEdges
=
rawData
.
links
||
rawData
.
edges
||
[]
rawEdges
.
forEach
((
edge
,
index
)
=>
{
const
source
=
String
(
edge
.
source
)
const
target
=
String
(
edge
.
target
)
const
edgeKey
=
`
${
source
}
-
${
target
}
`
if
(
edgeMap
.
has
(
edgeKey
))
{
return
}
if
(
!
nodeMap
.
has
(
source
)
||
!
nodeMap
.
has
(
target
))
{
return
}
edgeMap
.
set
(
edgeKey
,
true
)
edges
.
push
({
id
:
`edge-
${
index
}
`
,
source
,
target
,
label
:
edge
.
name
||
''
})
})
return
{
nodes
,
edges
}
}
const
bindGraphEvents
=
()
=>
{
if
(
!
graphInstance
.
value
)
return
graphInstance
.
value
.
on
(
'node:click'
,
(
evt
)
=>
{
const
node
=
evt
.
item
const
model
=
node
.
getModel
()
selectedNode
.
value
=
model
emit
(
'nodeClick'
,
model
)
})
graphInstance
.
value
.
on
(
'canvas:click'
,
()
=>
{
selectedNode
.
value
=
null
})
}
const
handleClickControlBtn
=
(
btn
)
=>
{
currentLayoutType
.
value
=
btn
emit
(
'layoutChange'
,
btn
)
initGraph
(
btn
)
}
const
destroyGraph
=
()
=>
{
if
(
graphInstance
.
value
)
{
graphInstance
.
value
.
destroy
()
graphInstance
.
value
=
null
}
}
const
handleResize
=
()
=>
{
if
(
graphInstance
.
value
&&
containerRef
.
value
)
{
const
width
=
containerRef
.
value
.
offsetWidth
const
height
=
containerRef
.
value
.
offsetHeight
graphInstance
.
value
.
changeSize
(
width
,
height
)
graphInstance
.
value
.
fitView
()
}
}
watch
(
()
=>
props
.
graphData
,
()
=>
{
initGraph
(
currentLayoutType
.
value
)
},
{
deep
:
true
}
)
watch
(
()
=>
props
.
treeData
,
()
=>
{
if
(
currentLayoutType
.
value
===
2
)
{
initGraph
(
2
)
}
},
{
deep
:
true
}
)
watch
(
()
=>
props
.
controlActive
,
(
newVal
)
=>
{
if
(
newVal
!==
currentLayoutType
.
value
)
{
handleClickControlBtn
(
newVal
)
}
}
)
onMounted
(()
=>
{
initGraph
(
1
)
window
.
addEventListener
(
'resize'
,
handleResize
)
})
onUnmounted
(()
=>
{
window
.
removeEventListener
(
'resize'
,
handleResize
)
destroyGraph
()
})
defineExpose
({
refresh
:
()
=>
initGraph
(
currentLayoutType
.
value
),
changeLayout
:
(
type
)
=>
handleClickControlBtn
(
type
),
getGraph
:
()
=>
graphInstance
.
value
})
</
script
>
<
style
lang=
"scss"
scoped
>
.relation-graph-wrapper
{
position
:
relative
;
width
:
100%
;
height
:
100%
;
}
.graph-container
{
width
:
100%
;
height
:
100%
;
}
.graph-controls
{
position
:
absolute
;
top
:
16px
;
right
:
16px
;
display
:
flex
;
gap
:
8px
;
z-index
:
10
;
.control-btn
{
width
:
32px
;
height
:
32px
;
border-radius
:
4px
;
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
cursor
:
pointer
;
img
{
width
:
16px
;
height
:
16px
;
}
&
:hover
{
border-color
:
rgba
(
5
,
95
,
194
,
0
.5
);
}
}
.control-btn-active
{
border-color
:
rgba
(
5
,
95
,
194
,
1
);
background
:
rgba
(
231
,
243
,
255
,
1
);
}
}
.node-popup
{
position
:
absolute
;
bottom
:
16px
;
left
:
16px
;
width
:
320px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
border-radius
:
8px
;
box-shadow
:
0px
4px
16px
rgba
(
0
,
0
,
0
,
0
.1
);
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
z-index
:
20
;
.popup-header
{
display
:
flex
;
align-items
:
center
;
padding
:
12px
16px
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
.popup-icon
{
width
:
32px
;
height
:
32px
;
margin-right
:
8px
;
border-radius
:
50%
;
object-fit
:
cover
;
}
.popup-title
{
flex
:
1
;
font-size
:
16px
;
font-weight
:
700
;
font-family
:
"Microsoft YaHei"
;
color
:
rgba
(
59
,
65
,
75
,
1
);
white-space
:
nowrap
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
}
.close-icon
{
cursor
:
pointer
;
color
:
rgba
(
132
,
136
,
142
,
1
);
font-size
:
16px
;
&
:hover
{
color
:
rgba
(
5
,
95
,
194
,
1
);
}
}
}
.popup-body
{
padding
:
12px
16px
;
.tag-row
{
display
:
flex
;
align-items
:
center
;
margin-bottom
:
8px
;
.red-dot
{
width
:
6px
;
height
:
6px
;
border-radius
:
50%
;
background
:
rgba
(
245
,
63
,
63
,
1
);
margin-right
:
8px
;
}
.red-text
{
font-size
:
14px
;
font-family
:
"Microsoft YaHei"
;
color
:
rgba
(
245
,
63
,
63
,
1
);
}
}
.desc
{
font-size
:
14px
;
font-family
:
"Microsoft YaHei"
;
line-height
:
22px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
margin
:
0
;
}
}
}
</
style
>
\ No newline at end of file
src/views/exportControl/v2.0SingleSanction/components/deepMining/index.vue
浏览文件 @
95f8d886
...
...
@@ -9,63 +9,6 @@
</div>
<div
class=
"main"
v-if=
"activeIndex === 0"
>
<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=
"filter-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=
"searchText"
placeholder=
"搜索实体"
class=
"search-input"
>
<template
#
suffix
>
<el-icon
class=
"el-input__icon"
><Search
/></el-icon>
</
template
>
</el-input>
</div>
<div
class=
"entity-tree custom-scrollbar"
>
<div
class=
"tree-group"
v-for=
"group in entityList"
:key=
"group.id"
>
<div
class=
"group-header"
@
click=
"toggleGroup(group)"
>
<el-icon
class=
"arrow-icon"
:class=
"{ expanded: group.expanded }"
>
<CaretRight
/>
</el-icon>
<span
class=
"group-name"
>
{{ group.name }}
</span>
<span
class=
"group-count"
>
{{ group.count }}家
</span>
</div>
<div
class=
"group-children custom-scrollbar"
v-show=
"group.expanded"
>
<div
class=
"entity-item"
v-for=
"item in group.children"
:key=
"item.id"
:class=
"{ active: activeEntityId === item.id }"
@
click=
"selectEntity(item)"
>
<div
class=
"item-icon"
>
<img
:src=
"defaultTitle"
alt=
""
class=
"item-img"
/>
</div>
<span
class=
"item-name"
>
{{ item.name }}
</span>
</div>
</div>
</div>
</div>
</div>
-->
<AnalysisBox
title=
"本次制裁实体清单列表"
>
<div
class=
"left-main"
>
<div
class=
"filter-bar"
>
...
...
@@ -134,26 +77,6 @@
<div
class=
"rule-checkbox"
v-if=
"rightActiveTab === 'equity'"
>
<el-checkbox
v-model=
"is50PercentRule"
size=
"large"
>
50%规则涉及实体
</el-checkbox>
</div>
<!-- <el-select v-model="filterType" placeholder="全部类型" class="header-select">
<el-option label="全部类型" value="" />
</el-select>
<el-select v-model="filterDomain" placeholder="全部领域" class="header-select last-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> -->
<div
class=
"btn"
>
<img
src=
"../../assets/数据库按钮.png"
alt=
""
/>
<img
src=
"../../assets/下载按钮.png"
alt=
""
/>
...
...
@@ -162,50 +85,14 @@
</div>
</div>
<div
class=
"right-echarts"
>
<div
class=
"chart-wrapper"
>
<div
class=
"chart-controls"
>
<div
class=
"control-btn"
:class=
"{ controlBtnActive: controlActive === 1 }"
@
click=
"handleClickControlBtn(1)"
>
<img
:src=
"echartsIcon01"
/>
</div>
<div
class=
"control-btn"
:class=
"{ controlBtnActive: controlActive === 2 }"
@
click=
"handleClickControlBtn(2)"
>
<img
:src=
"echartsIcon02"
/>
</div>
<div
class=
"control-btn"
:class=
"{ controlBtnActive: controlActive === 3 }"
@
click=
"handleClickControlBtn(3)"
>
<img
:src=
"echartsIcon03"
/>
</div>
</div>
<div
class=
"chart-legend"
>
<div
class=
"legend-item"
><span
class=
"dot blue"
></span>
已被制裁实体
</div>
<div
class=
"legend-item"
><span
class=
"dot grey"
></span>
未被制裁实体
</div>
</div>
<div
ref=
"chartRef"
id=
"chartbox"
class=
"chart-container"
></div>
<div
class=
"node-popup"
v-if=
"selectedNode"
>
<div
class=
"popup-header"
>
<img
:src=
"defaultTitle"
class=
"popup-icon"
/>
<span
class=
"popup-title"
>
{{ selectedNode.name.replace(/\n/g, "") }}
</span>
<el-icon
class=
"close-icon"
@
click=
"selectedNode = null"
>
<Close
/>
</el-icon>
</div>
<div
class=
"popup-body"
>
<div
class=
"tag-row"
>
<span
class=
"red-dot"
></span>
<span
class=
"red-text"
>
<!-- 2025年7月15日 《实体清单》 -->
暂无数据
</span>
</div>
<div
class=
"desc"
>
<!-- 因获取和试图获取美国原产物品以支持中国军事和国防相关空间领域活动以及中国量子技术能力而被列入。 -->
暂无数据
</div>
</div>
</div>
</div>
<RelationGraph
ref=
"relationGraphRef"
:graph-data=
"graphData"
:tree-data=
"treeData"
:control-active=
"controlActive"
@
node-click=
"handleNodeClick"
@
layout-change=
"handleLayoutChange"
/>
</div>
</div>
</div>
...
...
@@ -215,16 +102,12 @@
<
script
setup
>
import
{
ref
,
onMounted
,
nextTick
,
watch
,
onUnmounted
}
from
"vue"
;
import
{
debounce
}
from
"lodash"
;
import
*
as
echarts
from
"echarts"
;
import
{
Search
,
CaretRight
,
Close
}
from
"@element-plus/icons-vue"
;
import
defaultTitle
from
"../../assets/default-icon2.png"
;
import
icon01
from
"./assets/icon01.png"
;
import
icon02
from
"./assets/icon02.png"
;
import
icon01Active
from
"./assets/icon01-active.png"
;
import
icon02Active
from
"./assets/icon02-active.png"
;
import
echartsIcon01
from
"./assets/echartsIcon01.png"
;
import
echartsIcon02
from
"./assets/echartsIcon02.png"
;
import
echartsIcon03
from
"./assets/echartsIcon03.png"
;
import
company
from
"./assets/company.png"
;
import
companyActive
from
"./assets/company-active.png"
;
import
{
...
...
@@ -232,137 +115,10 @@ import {
getSingleSanctionEntitySupplyChain
,
getSingleSanctionEntityEquity
}
from
"@/api/exportControlV2.0"
;
import
getTreeChart
from
"./utils/treeChart"
;
import
setChart
from
"@/utils/setChart"
;
const
controlActive
=
ref
(
1
);
const
treeData
=
ref
([{}]);
const
handleClickControlBtn
=
btn
=>
{
controlActive
.
value
=
btn
;
if
(
btn
===
1
||
btn
===
3
)
{
isInChart
.
value
=
true
;
initChart
();
}
else
if
(
btn
===
2
)
{
isInChart
.
value
=
false
;
if
(
chartInstance
.
value
)
{
chartInstance
.
value
.
dispose
();
}
console
.
log
(
"treeData"
,
treeData
.
value
);
let
treeChart
=
getTreeChart
(
treeData
.
value
);
setChart
(
treeChart
,
"chartbox"
);
}
};
const
isInChart
=
ref
(
false
);
const
handleMouseEnter
=
()
=>
{
if
(
controlActive
.
value
!==
2
)
{
isInChart
.
value
=
true
;
}
else
{
isInChart
.
value
=
false
;
}
};
const
handleMouseLeave
=
()
=>
{
isInChart
.
value
=
false
;
};
// 单次制裁-深度挖掘-制裁实体股权信息-列表
const
singleSanctionEntityEquityData
=
ref
(
null
);
// 单次制裁-深度挖掘-制裁实体股权信息-请求
const
getSingleSanctionEntityEquityRequest
=
async
()
=>
{
try
{
const
res
=
await
getSingleSanctionEntityEquity
({
orgId
:
activeEntityId
.
value
,
rule
:
is50PercentRule
.
value
});
if
(
res
.
code
===
200
)
{
singleSanctionEntityEquityData
.
value
=
res
.
data
||
null
;
initChart
();
}
}
catch
(
error
)
{
console
.
log
(
error
);
}
};
// 单次制裁-深度挖掘-制裁实体供应链信息-列表
const
singleSanctionEntitySupplyChainData
=
ref
(
null
);
// 单次制裁-深度挖掘-制裁实体供应链信息-请求
const
getSingleSanctionEntitySupplyChainRequest
=
async
()
=>
{
try
{
const
res
=
await
getSingleSanctionEntitySupplyChain
({
orgId
:
activeEntityId
.
value
});
if
(
res
.
code
===
200
)
{
singleSanctionEntitySupplyChainData
.
value
=
res
.
data
||
null
;
initChart
();
treeData
.
value
[
0
].
id
=
res
.
data
.
orgId
;
treeData
.
value
[
0
].
name
=
res
.
data
.
orgName
;
treeData
.
value
[
0
].
symbol
=
"image://"
+
companyActive
;
treeData
.
value
[
0
].
symbolSize
=
50
;
treeData
.
value
[
0
].
value
=
10
;
treeData
.
value
[
0
].
children
=
res
.
data
.
parentOrgList
.
map
(
item
=>
{
return
{
id
:
item
.
id
,
name
:
item
.
name
,
symbolSize
:
30
,
value
:
10
,
symbol
:
`image://
${
company
}
`
};
});
console
.
log
(
"treeData0"
,
treeData
.
value
);
}
}
catch
(
error
)
{
console
.
log
(
error
);
}
};
// 单次制裁-深度挖掘-本次制裁实体清单列表
const
singleSanctionEntityList
=
ref
([]);
// 单次制裁-深度挖掘-本次制裁实体清单列表-请求
const
getSingleSanctionEntityListRequest
=
async
()
=>
{
try
{
const
res
=
await
getSingleSanctionEntityList
({
sanRecordId
:
sanRecordId
.
value
,
isOnlyCn
:
false
,
domainId
:
searchDomain
.
value
||
undefined
,
searchText
:
searchText
.
value
||
undefined
});
if
(
res
.
code
===
200
)
{
entityList
.
value
=
(
res
.
data
||
[]).
map
((
group
,
index
)
=>
({
id
:
`group-
${
index
}
`
,
name
:
group
.
orgType
,
count
:
group
.
orgInfoList
?
group
.
orgInfoList
.
length
:
0
,
expanded
:
index
===
0
,
// 默认展开第一个分组
children
:
(
group
.
orgInfoList
||
[]).
map
(
org
=>
({
id
:
org
.
id
,
name
:
org
.
orgNameZh
}))
}));
// 如果有数据,且当前没有选中的实体,默认选中第一个分组的第一个实体
if
(
entityList
.
value
.
length
>
0
&&
entityList
.
value
[
0
].
children
&&
entityList
.
value
[
0
].
children
.
length
>
0
)
{
const
firstEntity
=
entityList
.
value
[
0
].
children
[
0
];
if
(
!
activeEntityId
.
value
)
{
activeEntityId
.
value
=
firstEntity
.
id
;
currentEntityName
.
value
=
firstEntity
.
name
;
}
}
}
}
catch
(
error
)
{
console
.
log
(
error
);
}
};
import
RelationGraph
from
'./components/RelationGraph.vue'
;
import
AnalysisBox
from
'@/components/base/boxBackground/analysisBox.vue'
;
const
sanRecordId
=
ref
(
""
);
const
getUrlParams
=
()
=>
{
const
urlParams
=
new
URLSearchParams
(
window
.
location
.
search
);
sanRecordId
.
value
=
urlParams
.
get
(
"id"
)
||
""
;
};
// const activeTab = ref(["实体穿透分析", "重点实体识别"]);
const
activeTab
=
ref
([
"实体穿透分析"
]);
const
activeIndex
=
ref
(
0
);
const
rightActiveTab
=
ref
(
"supplyChain"
);
...
...
@@ -376,6 +132,22 @@ const currentEntityName = ref("");
const
is50PercentRule
=
ref
(
false
);
const
entityList
=
ref
([]);
const
controlActive
=
ref
(
1
);
const
isInChart
=
ref
(
false
);
const
relationGraphRef
=
ref
(
null
);
const
graphData
=
ref
({
nodes
:
[],
links
:
[]
});
const
treeData
=
ref
(
null
);
const
selectedNode
=
ref
(
null
);
const
singleSanctionEntityEquityData
=
ref
(
null
);
const
singleSanctionEntitySupplyChainData
=
ref
(
null
);
const
singleSanctionEntityList
=
ref
([]);
const
getUrlParams
=
()
=>
{
const
urlParams
=
new
URLSearchParams
(
window
.
location
.
search
);
sanRecordId
.
value
=
urlParams
.
get
(
"id"
)
||
""
;
};
const
toggleGroup
=
group
=>
{
group
.
expanded
=
!
group
.
expanded
;
...
...
@@ -386,512 +158,194 @@ const selectEntity = item => {
currentEntityName
.
value
=
item
.
name
;
};
const
chartRef
=
ref
(
null
);
const
chartInstance
=
ref
(
null
);
const
selectedNode
=
ref
(
null
);
const
initChart
=
()
=>
{
if
(
!
chartRef
.
value
)
return
;
if
(
chartInstance
.
value
)
{
chartInstance
.
value
.
dispose
();
const
handleMouseEnter
=
()
=>
{
if
(
controlActive
.
value
!==
2
)
{
isInChart
.
value
=
true
;
}
else
{
isInChart
.
value
=
false
;
}
};
chartInstance
.
value
=
echarts
.
init
(
chartRef
.
value
);
const
handleMouseLeave
=
()
=>
{
isInChart
.
value
=
false
;
};
let
option
=
{};
const
handleNodeClick
=
(
node
)
=>
{
selectedNode
.
value
=
node
;
};
if
(
rightActiveTab
.
value
===
"supplyChain"
)
{
option
=
getSupplyChainOption
();
const
handleLayoutChange
=
(
type
)
=>
{
controlActive
.
value
=
type
;
if
(
type
!==
2
)
{
isInChart
.
value
=
true
;
}
else
{
option
=
getEquityOption
()
;
isInChart
.
value
=
false
;
}
chartInstance
.
value
.
setOption
(
option
);
chartInstance
.
value
.
on
(
"click"
,
params
=>
{
if
(
params
.
dataType
===
"node"
)
{
selectedNode
.
value
=
params
.
data
;
}
else
{
selectedNode
.
value
=
null
;
}
});
chartInstance
.
value
.
getZr
().
on
(
"click"
,
params
=>
{
if
(
!
params
.
target
)
{
selectedNode
.
value
=
null
;
}
});
};
const
getSupplyChainOption
=
()
=>
{
if
(
!
singleSanctionEntitySupplyChainData
.
value
)
return
{};
const
data
=
singleSanctionEntitySupplyChainData
.
value
;
const
updateGraphData
=
()
=>
{
const
data
=
rightActiveTab
.
value
===
'supplyChain'
?
singleSanctionEntitySupplyChainData
.
value
:
singleSanctionEntityEquityData
.
value
;
if
(
!
data
)
return
;
const
nodes
=
[];
const
links
=
[];
const
centerX
=
550
;
const
centerY
=
400
;
// 中心节点
nodes
.
push
({
id
:
"0"
,
name
:
data
.
orgName
,
category
:
0
,
// 强制为制裁中
symbol
:
"image://"
+
companyActive
,
// 强制使用制裁中图标
x
:
centerX
,
y
:
centerY
,
symbolSize
:
50
,
label
:
{
fontSize
:
16
,
fontWeight
:
"bold"
,
color
:
"#055FC2"
,
// 使用制裁蓝,在图标下方更清晰
position
:
"bottom"
,
distance
:
10
,
width
:
150
,
overflow
:
"break"
}
image
:
companyActive
,
symbolSize
:
60
,
isSanctioned
:
true
});
// 父级节点 (供应商)
const
parentList
=
data
.
parentOrgList
||
[];
parentList
.
forEach
((
item
,
index
)
=>
{
// 使用 (index + 0.5) 使节点在半圆弧内居中分布
const
angle
=
-
Math
.
PI
+
((
index
+
0.5
)
/
parentList
.
length
)
*
Math
.
PI
;
// 交错半径:偶数索引使用 340,奇数索引使用 440,拉开垂直距离
const
radius
=
index
%
2
===
0
?
340
:
440
;
const
x
=
centerX
+
radius
*
Math
.
cos
(
angle
);
const
y
=
centerY
+
radius
*
Math
.
sin
(
angle
);
// 动态计算标签位置:根据余弦值判断左右,根据正弦值判断上下
let
position
=
"right"
;
let
align
=
"left"
;
const
cosA
=
Math
.
cos
(
angle
);
const
sinA
=
Math
.
sin
(
angle
);
if
(
Math
.
abs
(
cosA
)
<
0.3
)
{
// 顶部区域
position
=
"top"
;
align
=
"center"
;
}
else
if
(
cosA
<
0
)
{
// 左侧区域
position
=
"left"
;
align
=
"right"
;
}
nodes
.
push
({
id
:
`p-
${
item
.
id
}
`
,
id
:
`p-
${
item
.
id
||
index
}
`
,
name
:
item
.
name
,
category
:
item
.
isSanctioned
?
0
:
1
,
symbol
:
"image://"
+
(
item
.
isSanctioned
?
companyActive
:
company
),
x
:
x
,
y
:
y
,
isSanctioned
:
item
.
isSanctioned
,
label
:
{
position
:
position
,
align
:
align
,
distance
:
8
,
width
:
110
,
overflow
:
"break"
,
lineHeight
:
14
,
fontSize
:
11
}
image
:
item
.
isSanctioned
?
companyActive
:
company
,
symbolSize
:
40
,
isSanctioned
:
item
.
isSanctioned
});
links
.
push
({
source
:
`p-
${
item
.
id
}
`
,
source
:
`p-
${
item
.
id
||
index
}
`
,
target
:
"0"
,
value
:
"供应商"
,
isSanctioned
:
item
.
isSanctioned
&&
data
.
isSanctioned
name
:
rightActiveTab
.
value
===
'supplyChain'
?
"供应商"
:
(
item
.
type
||
"持股"
)
});
});
// 子级节点 (客户)
const
childList
=
data
.
childrenOrgList
||
[];
childList
.
forEach
((
item
,
index
)
=>
{
const
angle
=
((
index
+
0.5
)
/
childList
.
length
)
*
Math
.
PI
;
// 交错半径
const
radius
=
index
%
2
===
0
?
340
:
440
;
const
x
=
centerX
+
radius
*
Math
.
cos
(
angle
);
const
y
=
centerY
+
radius
*
Math
.
sin
(
angle
);
// 动态计算标签位置
let
position
=
"right"
;
let
align
=
"left"
;
const
cosA
=
Math
.
cos
(
angle
);
const
sinA
=
Math
.
sin
(
angle
);
if
(
Math
.
abs
(
cosA
)
<
0.3
)
{
// 底部区域
position
=
"bottom"
;
align
=
"center"
;
}
else
if
(
cosA
<
0
)
{
// 左侧区域
position
=
"left"
;
align
=
"right"
;
}
nodes
.
push
({
id
:
`c-
${
item
.
id
}
`
,
id
:
`c-
${
item
.
id
||
index
}
`
,
name
:
item
.
name
,
category
:
item
.
isSanctioned
?
0
:
1
,
symbol
:
"image://"
+
(
item
.
isSanctioned
?
companyActive
:
company
),
x
:
x
,
y
:
y
,
isSanctioned
:
item
.
isSanctioned
,
label
:
{
position
:
position
,
align
:
align
,
distance
:
8
,
width
:
110
,
overflow
:
"break"
,
lineHeight
:
14
,
fontSize
:
11
}
image
:
item
.
isSanctioned
?
companyActive
:
company
,
symbolSize
:
40
,
isSanctioned
:
item
.
isSanctioned
});
links
.
push
({
source
:
"0"
,
target
:
`c-
${
item
.
id
}
`
,
value
:
"客户"
,
isSanctioned
:
item
.
isSanctioned
&&
data
.
isSanctioned
target
:
`c-
${
item
.
id
||
index
}
`
,
name
:
rightActiveTab
.
value
===
'supplyChain'
?
"客户"
:
(
item
.
type
||
"投资"
)
});
});
return
{
tooltip
:
{
show
:
true
,
formatter
:
params
=>
{
if
(
params
.
dataType
===
"node"
)
{
return
`<div style="padding: 8px; max-width: 300px; white-space: normal; word-break: break-all;">
${
params
.
data
.
name
}
</div>`
;
}
return
""
;
}
},
series
:
[
{
type
:
"graph"
,
layout
:
"none"
,
symbolSize
:
36
,
roam
:
true
,
label
:
{
show
:
true
,
formatter
:
"{b}"
,
fontSize
:
12
,
hideOverlap
:
true
},
edgeSymbol
:
[
"none"
,
"arrow"
],
edgeSymbolSize
:
[
4
,
8
],
edgeLabel
:
{
position
:
"middle"
,
offset
:
[
0
,
13
],
fontSize
:
12
,
fontWeight
:
400
,
fontFamily
:
"Microsoft YaHei"
,
lineHeight
:
16
,
show
:
true
,
formatter
:
"{c}"
,
color
:
"rgba(170, 173, 177, 1)"
,
backgroundColor
:
"rgba(234, 236, 238, 1)"
,
padding
:
[
4
,
8
],
borderRadius
:
20
},
data
:
nodes
.
map
(
node
=>
({
...
node
,
label
:
{
color
:
node
.
category
===
0
?
"#055FC2"
:
"#5F656C"
,
...
node
.
label
}
})),
links
:
links
.
map
(
link
=>
{
return
{
...
link
,
lineStyle
:
{
color
:
link
.
isSanctioned
?
"rgba(100, 180, 255, 1)"
:
"rgb(180, 181, 182)"
,
width
:
1
,
curveness
:
0
},
label
:
link
.
isSanctioned
?
{
show
:
true
,
formatter
:
"{c}"
,
backgroundColor
:
"rgba(231, 243, 255, 1)"
,
color
:
"rgba(50, 150, 250, 1)"
,
borderRadius
:
20
,
padding
:
[
4
,
8
],
fontSize
:
12
,
fontWeight
:
400
,
fontFamily
:
"Microsoft YaHei"
,
lineHeight
:
16
}
:
undefined
};
})
}
]
};
graphData
.
value
=
{
nodes
,
links
};
};
const
getEquityOption
=
()
=>
{
if
(
!
singleSanctionEntityEquityData
.
value
)
return
{};
const
data
=
singleSanctionEntityEquityData
.
value
;
const
nodes
=
[];
const
links
=
[];
const
centerX
=
550
;
const
centerY
=
400
;
const
updateTreeData
=
(
data
)
=>
{
if
(
!
data
)
return
;
// 中心节点
nodes
.
push
({
id
:
"0"
,
treeData
.
value
=
{
id
:
data
.
orgId
,
name
:
data
.
orgName
,
category
:
0
,
// 强制为制裁中
symbol
:
"image://"
+
companyActive
,
// 强制使用制裁中图标
x
:
centerX
,
y
:
centerY
,
image
:
companyActive
,
symbolSize
:
50
,
label
:
{
fontSize
:
16
,
fontWeight
:
"bold"
,
color
:
"#055FC2"
,
// 使用制裁蓝,在图标下方更清晰
position
:
"bottom"
,
distance
:
10
,
width
:
150
,
overflow
:
"break"
}
});
// 父级节点 (股东)
const
parentList
=
data
.
parentOrgList
||
[];
parentList
.
forEach
((
item
,
index
)
=>
{
// 在顶部水平排列
const
total
=
parentList
.
length
;
const
gap
=
200
;
const
startX
=
centerX
-
((
total
-
1
)
*
gap
)
/
2
;
const
x
=
startX
+
index
*
gap
;
const
y
=
centerY
-
250
;
// 向上偏移
nodes
.
push
({
id
:
`p-
${
index
}
`
,
children
:
(
data
.
parentOrgList
||
[]).
map
((
item
,
index
)
=>
({
id
:
item
.
id
||
`p-
${
index
}
`
,
name
:
item
.
name
,
category
:
item
.
isSanctioned
?
0
:
1
,
symbol
:
"image://"
+
(
item
.
isSanctioned
?
companyActive
:
company
),
x
:
x
,
y
:
y
,
isSanctioned
:
item
.
isSanctioned
,
label
:
{
position
:
"top"
,
distance
:
8
,
width
:
110
,
overflow
:
"break"
,
lineHeight
:
14
,
fontSize
:
11
}
});
image
:
item
.
isSanctioned
?
companyActive
:
company
,
symbolSize
:
30
}))
};
};
links
.
push
(
{
source
:
`p-
${
index
}
`
,
target
:
"0"
,
value
:
item
.
type
||
"持股"
,
// 使用 type 字段
isSanctioned
:
item
.
isSanctioned
// 中心节点强制制裁,高亮取决于对方
const
getSingleSanctionEntityEquityRequest
=
async
()
=>
{
try
{
const
res
=
await
getSingleSanctionEntityEquity
({
orgId
:
activeEntityId
.
value
,
rule
:
is50PercentRule
.
value
});
});
// 子级节点 (对外投资)
const
childList
=
data
.
childrenOrgList
||
[];
childList
.
forEach
((
item
,
index
)
=>
{
// 在底部水平排列
const
total
=
childList
.
length
;
const
gap
=
240
;
// 稍微拉开一点间距
const
startX
=
centerX
-
((
total
-
1
)
*
gap
)
/
2
;
const
x
=
startX
+
index
*
gap
;
const
y
=
centerY
+
250
;
// 向下偏移
if
(
res
.
code
===
200
)
{
singleSanctionEntityEquityData
.
value
=
res
.
data
||
null
;
updateGraphData
();
}
}
catch
(
error
)
{
console
.
log
(
error
);
}
};
nodes
.
push
({
id
:
`c-
${
index
}
`
,
name
:
item
.
name
,
category
:
item
.
isSanctioned
?
0
:
1
,
symbol
:
"image://"
+
(
item
.
isSanctioned
?
companyActive
:
company
),
x
:
x
,
y
:
y
,
isSanctioned
:
item
.
isSanctioned
,
label
:
{
position
:
"bottom"
,
distance
:
8
,
width
:
110
,
overflow
:
"break"
,
lineHeight
:
14
,
fontSize
:
11
}
const
getSingleSanctionEntitySupplyChainRequest
=
async
()
=>
{
try
{
const
res
=
await
getSingleSanctionEntitySupplyChain
({
orgId
:
activeEntityId
.
value
});
if
(
res
.
code
===
200
)
{
singleSanctionEntitySupplyChainData
.
value
=
res
.
data
||
null
;
updateGraphData
();
updateTreeData
(
res
.
data
);
}
}
catch
(
error
)
{
console
.
log
(
error
);
}
};
links
.
push
({
source
:
"0"
,
target
:
`c-
${
index
}
`
,
value
:
item
.
type
||
"持股"
,
// 使用 type 字段
isSanctioned
:
item
.
isSanctioned
// 中心节点强制制裁,高亮取决于对方
const
getSingleSanctionEntityListRequest
=
async
()
=>
{
try
{
const
res
=
await
getSingleSanctionEntityList
({
sanRecordId
:
sanRecordId
.
value
,
isOnlyCn
:
false
,
domainId
:
searchDomain
.
value
||
undefined
,
searchText
:
searchText
.
value
||
undefined
});
});
if
(
res
.
code
===
200
)
{
entityList
.
value
=
(
res
.
data
||
[]).
map
((
group
,
index
)
=>
({
id
:
`group-
${
index
}
`
,
name
:
group
.
orgType
,
count
:
group
.
orgInfoList
?
group
.
orgInfoList
.
length
:
0
,
expanded
:
index
===
0
,
children
:
(
group
.
orgInfoList
||
[]).
map
(
org
=>
({
id
:
org
.
id
,
name
:
org
.
orgNameZh
}))
}));
return
{
tooltip
:
{
show
:
true
,
formatter
:
params
=>
{
if
(
params
.
dataType
===
"node"
)
{
return
`<div style="padding: 8px; max-width: 300px; white-space: normal; word-break: break-all;">
${
params
.
data
.
name
}
</div>`
;
if
(
entityList
.
value
.
length
>
0
&&
entityList
.
value
[
0
].
children
&&
entityList
.
value
[
0
].
children
.
length
>
0
)
{
const
firstEntity
=
entityList
.
value
[
0
].
children
[
0
];
if
(
!
activeEntityId
.
value
)
{
activeEntityId
.
value
=
firstEntity
.
id
;
currentEntityName
.
value
=
firstEntity
.
name
;
}
return
""
;
}
},
series
:
[
{
type
:
"graph"
,
layout
:
"none"
,
symbolSize
:
36
,
roam
:
true
,
label
:
{
show
:
true
,
formatter
:
"{b}"
,
fontSize
:
12
,
hideOverlap
:
true
},
edgeSymbol
:
[
"none"
,
"arrow"
],
edgeSymbolSize
:
[
4
,
8
],
edgeLabel
:
{
position
:
"middle"
,
offset
:
[
0
,
13
],
fontSize
:
12
,
fontWeight
:
400
,
fontFamily
:
"Microsoft YaHei"
,
lineHeight
:
16
,
show
:
true
,
formatter
:
"{c}"
,
color
:
"rgba(170, 173, 177, 1)"
,
backgroundColor
:
"rgba(234, 236, 238, 1)"
,
padding
:
[
4
,
8
],
borderRadius
:
20
},
data
:
nodes
.
map
(
node
=>
({
...
node
,
label
:
{
color
:
node
.
category
===
0
?
"#055FC2"
:
"#5F656C"
,
...
node
.
label
}
})),
links
:
links
.
map
(
link
=>
{
return
{
...
link
,
lineStyle
:
{
color
:
link
.
isSanctioned
?
"rgba(100, 180, 255, 1)"
:
"rgb(180, 181, 182)"
,
width
:
1
,
curveness
:
0
},
label
:
link
.
isSanctioned
?
{
show
:
true
,
formatter
:
"{c}"
,
backgroundColor
:
"rgba(231, 243, 255, 1)"
,
color
:
"rgba(50, 150, 250, 1)"
,
borderRadius
:
20
,
padding
:
[
4
,
8
],
fontSize
:
12
,
fontWeight
:
400
,
fontFamily
:
"Microsoft YaHei"
,
lineHeight
:
16
}
:
undefined
};
})
}
]
};
}
}
catch
(
error
)
{
console
.
log
(
error
);
}
};
const
debouncedGetList
=
debounce
(()
=>
{
getSingleSanctionEntityListRequest
();
},
1000
);
watch
(
searchText
,
()
=>
{
debouncedGetList
();
});
watch
(
searchDomain
,
()
=>
{
getSingleSanctionEntityListRequest
();
});
watch
(
activeIndex
,
val
=>
{
if
(
val
===
0
)
{
nextTick
(()
=>
{
if
(
activeEntityId
.
value
)
{
if
(
rightActiveTab
.
value
===
"supplyChain"
)
{
getSingleSanctionEntitySupplyChainRequest
();
}
else
{
getSingleSanctionEntityEquityRequest
();
}
}
initChart
();
});
watch
(
rightActiveTab
,
async
(
newTab
)
=>
{
if
(
newTab
===
'supplyChain'
)
{
await
getSingleSanctionEntitySupplyChainRequest
();
}
else
{
await
getSingleSanctionEntityEquityRequest
();
}
});
watch
(
activeEntityId
,
val
=>
{
if
(
val
)
{
if
(
rightActiveTab
.
value
===
"supplyChain"
)
{
getSingleSanctionEntitySupplyChainRequest
();
watch
(
activeEntityId
,
async
(
newId
)
=>
{
if
(
newId
)
{
if
(
rightActiveTab
.
value
===
'supplyChain'
)
{
await
getSingleSanctionEntitySupplyChainRequest
();
}
else
{
getSingleSanctionEntityEquityRequest
();
await
getSingleSanctionEntityEquityRequest
();
}
initChart
();
}
});
watch
(
is50PercentRule
,
()
=>
{
if
(
rightActiveTab
.
value
===
"equity"
&&
activeEntityId
.
value
)
{
getSingleSanctionEntityEquityRequest
();
watch
(
is50PercentRule
,
async
()
=>
{
if
(
rightActiveTab
.
value
===
'equity'
)
{
await
getSingleSanctionEntityEquityRequest
();
}
});
watch
(
rightActiveTab
,
val
=>
{
if
(
activeEntityId
.
value
)
{
if
(
val
===
"supplyChain"
)
{
getSingleSanctionEntitySupplyChainRequest
();
}
else
{
getSingleSanctionEntityEquityRequest
();
}
}
nextTick
(()
=>
{
initChart
();
});
},
{
immediate
:
true
}
);
onMounted
(()
=>
{
// 获取URL参数
onMounted
(
async
()
=>
{
getUrlParams
();
// 单次制裁-深度挖掘-本次制裁实体清单列表-请求
getSingleSanctionEntityListRequest
();
window
.
addEventListener
(
"resize"
,
handleResize
);
});
onUnmounted
(()
=>
{
if
(
chartInstance
.
value
)
{
chartInstance
.
value
.
dispose
();
}
if
(
debouncedGetList
&&
debouncedGetList
.
cancel
)
{
debouncedGetList
.
cancel
();
}
window
.
removeEventListener
(
"resize"
,
handleResize
);
await
getSingleSanctionEntityListRequest
();
});
const
handleResize
=
()
=>
{
if
(
chartInstance
.
value
)
{
chartInstance
.
value
.
resize
();
}
};
</
script
>
<
style
scoped
lang=
"scss"
>
...
...
src/views/finance/index.vue
浏览文件 @
95f8d886
...
...
@@ -550,7 +550,7 @@ const messageList = ref([
]);
// 查看更多风险信号
const
handleToMoreRiskSignal
=
()
=>
{
const
route
=
router
.
resolve
(
"/
r
iskSignal"
);
const
route
=
router
.
resolve
(
"/
viewR
iskSignal"
);
window
.
open
(
route
.
href
,
"_blank"
);
};
...
...
src/views/ruleRestriction/index.vue
浏览文件 @
95f8d886
...
...
@@ -3,8 +3,13 @@
<div
class=
"main-content"
ref=
"homeMainRef"
>
<div
class=
"home-top-bg"
></div>
<!-- 搜索栏部分 -->
<SearchContainer
v-if=
"homeMainRef"
:countInfo=
"statCountInfo"
placeholder=
"搜索规则限制"
:containerRef=
"homeMainRef"
areaName=
""
/>
<SearchContainer
v-if=
"homeMainRef"
:countInfo=
"statCountInfo"
placeholder=
"搜索规则限制"
:containerRef=
"homeMainRef"
areaName=
""
/>
<!-- 最新动态 -->
<div
class=
"newdata"
id=
"position1"
>
<com-title
title=
"最新动态"
/>
...
...
@@ -14,7 +19,7 @@
</div>
<!-- 资讯要问 -->
<div
class=
"ask"
id=
"position2"
>
<com-title
title=
"
咨询
要闻"
/>
<com-title
title=
"
资讯
要闻"
/>
<div
class=
"ask-main"
>
<askPage
/>
</div>
...
...
src/views/ruleRestriction/index2.vue
浏览文件 @
95f8d886
...
...
@@ -19,7 +19,7 @@
</div>
</div>
<div
class=
"btn"
@
click=
"handleToPosi('position2')"
>
<div
class=
"btn-text"
>
咨询
要闻
</div>
<div
class=
"btn-text"
>
资讯
要闻
</div>
<div
class=
"btn-icon"
>
<img
src=
"@/assets/icons/arrow-right-icon.png"
alt
/>
</div>
...
...
@@ -29,7 +29,8 @@
<div
class=
"btn-icon"
>
<img
src=
"@/assets/icons/arrow-right-icon.png"
alt
/>
</div>
</div>
,
</div>
,
<div
class=
"btn"
@
click=
"handleToPosi('position4')"
>
<div
class=
"btn-text"
>
资源库
</div>
<div
class=
"btn-icon"
>
...
...
@@ -85,7 +86,7 @@
</div>
</div>
<div
class=
"btn"
@
click=
"handleToPosi('position2')"
>
<div
class=
"btn-text"
>
咨询
要闻
</div>
<div
class=
"btn-text"
>
资讯
要闻
</div>
<div
class=
"btn-icon"
>
<img
src=
"@/assets/icons/arrow-right-icon.png"
alt
/>
</div>
...
...
@@ -113,7 +114,7 @@
</div>
<!-- 资讯要问 -->
<div
class=
"ask"
id=
"position2"
>
<com-title
title=
"
咨询
要闻"
/>
<com-title
title=
"
资讯
要闻"
/>
<div
class=
"ask-main"
>
<askPage
/>
</div>
...
...
@@ -145,7 +146,7 @@ import askPage from "./components/askPage/index.vue";
import
dataSub
from
"./components/dataSub/index.vue"
;
import
resLib
from
"./components/resLib/index.vue"
;
import
{
useContainerScroll
}
from
"@/hooks/useScrollShow"
;
import
{
getStatCount
}
from
'@/api/ruleRestriction/index.js'
import
{
getStatCount
}
from
"@/api/ruleRestriction/index.js"
;
// 搜索框
const
input
=
ref
(
""
);
...
...
@@ -154,59 +155,59 @@ const { isShow } = useContainerScroll(homeMainRef);
const
router
=
useRouter
();
const
statCountInfo
=
ref
({})
const
statCountInfo
=
ref
({})
;
const
getStatCountInfo
=
async
()
=>
{
try
{
const
res
=
await
getStatCount
();
if
(
res
&&
res
.
code
===
200
)
{
// console.log('----getStatCountInfo', res.data)
statCountInfo
.
value
=
res
.
data
}
}
catch
(
error
)
{
console
.
error
(
"获取首页统计接口失败:"
,
error
);
}
}
try
{
const
res
=
await
getStatCount
();
if
(
res
&&
res
.
code
===
200
)
{
// console.log('----getStatCountInfo', res.data)
statCountInfo
.
value
=
res
.
data
;
}
}
catch
(
error
)
{
console
.
error
(
"获取首页统计接口失败:"
,
error
);
}
}
;
// 搜索功能
const
handleSearch
=
()
=>
{
console
.
log
(
"搜索内容:"
,
input
.
value
);
console
.
log
(
"搜索内容:"
,
input
.
value
);
};
// 锚点跳转
const
handleToPosi
=
id
=>
{
const
element
=
document
.
getElementById
(
id
);
if
(
element
&&
homeMainRef
.
value
)
{
// 如果当前还未显示吸顶搜索栏,先强制切换状态以稳定布局
if
(
!
isShow
.
value
)
{
isShow
.
value
=
true
;
}
const
element
=
document
.
getElementById
(
id
);
if
(
element
&&
homeMainRef
.
value
)
{
// 如果当前还未显示吸顶搜索栏,先强制切换状态以稳定布局
if
(
!
isShow
.
value
)
{
isShow
.
value
=
true
;
}
// 使用 nextTick 确保 DOM 状态更新(高度变化生效)后再计算
nextTick
(()
=>
{
const
containerRect
=
homeMainRef
.
value
.
getBoundingClientRect
();
const
elementRect
=
element
.
getBoundingClientRect
();
// 使用 getBoundingClientRect 计算元素相对于容器顶部的绝对距离,不受嵌套布局影响
const
top
=
elementRect
.
top
-
containerRect
.
top
+
homeMainRef
.
value
.
scrollTop
;
// 使用 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"
});
});
}
homeMainRef
.
value
.
scrollTo
({
top
:
top
,
behavior
:
"smooth"
});
});
}
};
// 返回首页
const
handleBackHome
=
()
=>
{
router
.
push
({
path
:
"/overview"
});
router
.
push
({
path
:
"/overview"
});
};
onMounted
(
async
()
=>
{
await
getStatCountInfo
()
})
await
getStatCountInfo
();
})
;
</
script
>
<
style
scoped
lang=
"scss"
>
...
...
src/views/scientificFunding/index.vue
浏览文件 @
95f8d886
...
...
@@ -14,8 +14,14 @@
<div
class=
"main-content"
ref=
"containerRef"
>
<div
class=
"home-top-bg"
></div>
<!-- 搜索栏部分 -->
<SearchContainer
style=
"margin-bottom: 48px;height: fit-content;"
v-if=
"containerRef"
:countInfo=
"countInfo"
placeholder=
"搜索科研资助实体、资助记录"
:containerRef=
"containerRef"
areaName=
""
/>
<SearchContainer
style=
"margin-bottom: 48px; height: fit-content"
v-if=
"containerRef"
:countInfo=
"countInfo"
placeholder=
"搜索科研资助实体、资助记录"
:containerRef=
"containerRef"
areaName=
""
/>
<!--
<div
class=
"search"
>
-->
<!--
<div
class=
"search-main"
>
...
...
@@ -51,7 +57,7 @@
</div>
</div>
<div
class=
"btn"
@
click=
"scrollToTop('position2')"
>
<div
class=
"btn-text"
>
咨询
要闻
</div>
<div
class=
"btn-text"
>
资讯
要闻
</div>
<div
class=
"btn-icon"
>
<img
src=
"@/assets/icons/arrow-right-icon.png"
alt=
""
/>
</div>
...
...
@@ -80,7 +86,7 @@
<div
class=
"data-item-name"
>
{{
item
.
orgNameEn
}}
</div>
<div
v-if=
"item.orgAbbEn"
class=
"data-item-abb"
>
{{
item
.
orgAbbEn
}}
</div>
</div>
<div
class=
"data-item-num"
:style=
"
{ color: color[index] }">
{{
item
.
num
+
'项'
}}
</div>
<div
class=
"data-item-num"
:style=
"
{ color: color[index] }">
{{
item
.
num
+
"项"
}}
</div>
</div>
</div>
<!-- 最新动态 -->
...
...
@@ -92,7 +98,7 @@
</div>
<!-- 资讯要问 -->
<div
class=
"ask"
id=
"position2"
>
<com-title
title=
"
咨询
要闻"
/>
<com-title
title=
"
资讯
要闻"
/>
<div
class=
"ask-main"
>
<askPage
/>
</div>
...
...
@@ -125,10 +131,7 @@ import dataSub from "./components/dataSub/index.vue";
import
resLib
from
"./components/resLib/index.vue"
;
import
scrollToTop
from
"@/utils/scrollToTop"
;
import
{
getFundSourceOrg
}
from
"@/api/scientificFunding/overview"
;
import
{
getFundSourceOrg
}
from
"@/api/scientificFunding/overview"
;
import
{
useContainerScroll
}
from
"@/hooks/useScrollShow"
;
...
...
@@ -141,21 +144,21 @@ import img06 from "./assets/images/img06.png";
let
containerRef
=
ref
(
null
);
let
countInfo
=
ref
([
{
name
:
'科研资助机构'
,
name
:
"科研资助机构"
,
count
:
18
},
{
name
:
'科研资助动态'
,
name
:
"科研资助动态"
,
count
:
633
},
{
name
:
'科研资助项目'
,
name
:
"科研资助项目"
,
count
:
312
},
{
name
:
'经费总额(亿美元)'
,
count
:
'15,556'
}
,
name
:
"经费总额(亿美元)"
,
count
:
"15,556"
}
]);
// 搜索框
const
input
=
ref
(
""
);
...
...
@@ -231,14 +234,14 @@ const color = ref([
"rgba(64, 150, 255, 1)"
,
"rgb(33, 129, 57)"
,
"rgb(5, 95, 194)"
])
])
;
//// 来源机构列表
const
handleGetFundSourceOrg
=
async
()
=>
{
try
{
const
res
=
await
getFundSourceOrg
();
console
.
log
(
"来源机构列表"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
dataList
.
value
=
res
.
data
dataList
.
value
=
res
.
data
;
}
}
catch
(
error
)
{
console
.
error
(
"获取来源机构列表error"
,
error
);
...
...
@@ -246,7 +249,7 @@ const handleGetFundSourceOrg = async () => {
};
onMounted
(
async
()
=>
{
handleGetFundSourceOrg
()
handleGetFundSourceOrg
()
;
});
</
script
>
...
...
@@ -461,7 +464,9 @@ onMounted(async () => {
box-sizing
:
border-box
;
position
:
relative
;
cursor
:
pointer
;
transition
:
transform
0
.3s
ease
,
box-shadow
0
.3s
ease
;
transition
:
transform
0
.3s
ease
,
box-shadow
0
.3s
ease
;
display
:
flex
;
align-items
:
center
;
padding
:
0px
24px
;
...
...
vite.config.js
浏览文件 @
95f8d886
...
...
@@ -89,7 +89,8 @@ export default defineConfig({
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
temporarySearch/
,
''
)
},
'^/bill(?:/|$)'
:
{
target
:
'http://172.20.10.3:28080/'
,
target
:
'http://8.140.26.4:9085/'
,
// target: 'http://172.20.10.3:28080/',
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
bill/
,
''
)
},
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论