Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
094f43e3
提交
094f43e3
authored
3月 31, 2026
作者:
张伊明
浏览文件
操作
浏览文件
下载
差异文件
合并分支 'zz-dev' 到 'pre'
feat:修改合作限制动态的样式,将合作限制后端更改的数据展示出来;修改合作限制图表样式及下拉框样式,完善相关实体点击跳转对应页面功能 查看合并请求
!283
上级
c367ed1f
7a10f6fc
流水线
#245
已取消 于阶段
变更
6
流水线
1
显示空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
178 行增加
和
43 行删除
+178
-43
index.js
src/router/index.js
+2
-1
cooperationRestrictions.js
src/router/modules/cooperationRestrictions.js
+2
-1
index.vue
src/views/coopRestriction/components/dataNew/index.vue
+11
-8
index.vue
src/views/coopRestriction/components/dataSub/index.vue
+78
-14
index.vue
src/views/coopRestriction/components/resLib/index.vue
+17
-5
index.vue
src/views/coopRestriction/detail/index.vue
+68
-14
没有找到文件。
src/router/index.js
浏览文件 @
094f43e3
...
...
@@ -69,7 +69,8 @@ router.beforeEach((to, from, next) => {
if
(
to
.
meta
.
title
)
{
if
(
to
.
meta
.
dynamicTitle
)
{
console
.
log
(
'to'
,
to
);
document
.
title
=
window
.
sessionStorage
.
getItem
(
"curTabName"
)
||
to
.
meta
.
title
;
const
storageKey
=
to
.
meta
.
titleStorageKey
||
"curTabName"
;
document
.
title
=
window
.
sessionStorage
.
getItem
(
storageKey
)
||
to
.
meta
.
title
;
}
else
{
document
.
title
=
to
.
meta
.
title
...
...
src/router/modules/cooperationRestrictions.js
浏览文件 @
094f43e3
...
...
@@ -20,7 +20,8 @@ const cooperationRestrictionsRoutes = [
component
:
CooperationRestrictionsDetail
,
meta
:
{
title
:
"合作限制详情"
,
dynamicTitle
:
true
dynamicTitle
:
true
,
titleStorageKey
:
"cooperationRestrictionsTabName"
}
},
...
...
src/views/coopRestriction/components/dataNew/index.vue
浏览文件 @
094f43e3
...
...
@@ -6,7 +6,7 @@
<div
class=
"left-top"
>
<img
src=
"./assets/icon01.png"
alt=
""
/>
<div
class=
"left-top-title"
>
合作限制动态
</div>
<div
class=
"more"
@
click=
"handleClickToDetail"
>
查看详情 >
</div>
<div
class=
"more"
@
click=
"handleClickToDetail"
>
{{
"查看详情 >"
}}
</div>
</div>
<el-carousel
ref=
"carouselRef"
height=
"412px"
direction=
"horizontal"
:autoplay=
"true"
:interval=
"5000"
...
...
@@ -46,7 +46,7 @@
</div>
</div>
<div
class=
"left-center-type"
v-if=
"item.
type"
>
{{
item
.
type
}}
</div>
<div
class=
"left-center-type"
v-if=
"item.
limitMeans"
>
{{
item
.
limitMeans
}}
</div>
<!--
<div
class=
"left-center-title"
>
{{
item
.
LIMITTYPE
}}
</div>
-->
</div>
<div
class=
"left-bottom"
>
...
...
@@ -188,12 +188,12 @@ const riskSignals = ref([]);
// 点击查看详情
const
handleClickToDetail
=
item
=>
{
const
activeItem
=
item
&&
item
.
ID
?
item
:
mainTrend
.
value
;
const
id
=
activeItem
?.
ID
;
const
id
=
activeItem
?.
ID
||
activeItem
?.
id
||
activeItem
?.
limitId
;
if
(
!
id
)
return
;
window
.
sessionStorage
.
setItem
(
"c
urTabName"
,
activeItem
?.
LIMITNAME
);
window
.
sessionStorage
.
setItem
(
"c
ooperationRestrictionsTabName"
,
activeItem
?.
LIMITNAME
||
""
);
const
curRoute
=
router
.
resolve
({
path
:
"/cooperationRestrictions/d
etail"
,
name
:
"CooperationRestrictionsD
etail"
,
query
:
{
id
:
id
}
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
...
...
@@ -201,9 +201,11 @@ const handleClickToDetail = item => {
// 点击风险信号详情
const
handleToRiskDetail
=
(
item
)
=>
{
const
id
=
item
?.
cooperationId
||
item
?.
ID
||
item
?.
id
||
item
?.
limitId
;
if
(
!
id
)
return
;
const
curRoute
=
router
.
resolve
({
path
:
"/cooperationRestrictions/d
etail"
,
query
:
{
id
:
item
.
cooperationId
},
name
:
"CooperationRestrictionsD
etail"
,
query
:
{
id
},
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
};
...
...
@@ -318,7 +320,7 @@ onMounted(() => {
width
:
967px
;
height
:
208px
;
margin-top
:
33px
;
margin-left
:
62
px
;
margin-left
:
57
px
;
border-bottom
:
1px
solid
rgb
(
234
,
236
,
238
);
position
:
relative
;
...
...
@@ -326,6 +328,7 @@ onMounted(() => {
width
:
148px
;
height
:
148px
;
margin-right
:
21px
;
margin-left
:
5px
;
}
display
:
flex
;
...
...
src/views/coopRestriction/components/dataSub/index.vue
浏览文件 @
094f43e3
...
...
@@ -4,7 +4,8 @@
<div
class=
"left-title"
>
<img
src=
"./assets/icon01.png"
alt=
""
/>
<div
class=
"tit"
>
各类型合作限制政策对比
</div>
<el-select
v-model=
"value"
placeholder=
"Select"
class=
"select"
@
change=
"getCoopRestrictionCompareData"
>
<el-select
v-model=
"value"
placeholder=
"Select"
class=
"select"
popper-class=
"coop-select-dropdown"
@
change=
"getCoopRestrictionCompareData"
>
<el-option
v-for=
"item in options"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
...
...
@@ -34,7 +35,8 @@
<div
class=
"right-title"
>
<img
src=
"./assets/icon02.png"
alt=
""
/>
<div
class=
"tit"
>
各领域规则分布情况
</div>
<el-select
v-model=
"value1"
placeholder=
"Select"
class=
"select"
@
change=
"getCoopRestrictionDomainData"
>
<el-select
v-model=
"value1"
placeholder=
"Select"
class=
"select"
popper-class=
"coop-select-dropdown"
@
change=
"getCoopRestrictionDomainData"
>
<el-option
v-for=
"item in options1"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
...
...
@@ -75,6 +77,22 @@ import AiPane from "@/components/base/Ai/AiPane/index.vue";
const
COOP_LEFT_TIP_TEXT
=
"各类型合作限制政策对比,数据来源:美对华科技合作限制信息平台"
;
const
COOP_RIGHT_TIP_TEXT
=
"各领域规则分布情况,数据来源:美对华科技合作限制信息平台"
;
// 临时展示 mock(不改样式):右侧“各领域规则分布情况”
// 用完把这个开关改回 false 即可恢复走接口
const
USE_DOMAIN_MOCK
=
false
;
const
MOCK_COOP_RESTRICTION_DOMAIN
=
[
{
COOPERTYPE
:
"科研合作"
,
COOPERTYPECOUNT
:
1
,
AREA
:
"人工智能"
},
{
COOPERTYPE
:
"科研合作"
,
COOPERTYPECOUNT
:
1
,
AREA
:
"生物科技"
},
{
COOPERTYPE
:
"技术合作"
,
COOPERTYPECOUNT
:
2
,
AREA
:
"大数据"
},
{
COOPERTYPE
:
"产学研合作"
,
COOPERTYPECOUNT
:
3
,
AREA
:
"新能源"
},
{
COOPERTYPE
:
"项目合作"
,
COOPERTYPECOUNT
:
1
,
AREA
:
"智能制造"
},
{
COOPERTYPE
:
"人才合作"
,
COOPERTYPECOUNT
:
2
,
AREA
:
"集成电路"
},
{
COOPERTYPE
:
"科研合作"
,
COOPERTYPECOUNT
:
2
,
AREA
:
"大数据"
},
{
COOPERTYPE
:
"科研合作"
,
COOPERTYPECOUNT
:
3
,
AREA
:
"新能源"
},
{
COOPERTYPE
:
"科研合作"
,
COOPERTYPECOUNT
:
1
,
AREA
:
"智能制造"
},
{
COOPERTYPE
:
"科研合作"
,
COOPERTYPECOUNT
:
2
,
AREA
:
"集成电路"
}
];
const
value
=
ref
(
10
);
const
value1
=
ref
(
"2025"
);
const
options
=
[
...
...
@@ -109,6 +127,10 @@ const options1 = [
const
coopRestrictionDomain
=
ref
([]);
const
getCoopRestrictionDomainData
=
async
()
=>
{
if
(
USE_DOMAIN_MOCK
)
{
coopRestrictionDomain
.
value
=
MOCK_COOP_RESTRICTION_DOMAIN
;
return
;
}
try
{
const
res
=
await
getCoopRestrictionDomain
({
year
:
value1
.
value
...
...
@@ -449,10 +471,18 @@ const initLeftChart = () => {
const
option
=
{
color
:
colorMap
.
map
((
c
)
=>
c
.
line
),
grid
:
{
left
:
40
,
right
:
24
,
top
:
46
,
bottom
:
36
},
// 与智库概览「数量变化趋势」一致:预留图例空间,并用 containLabel 让轴文字不挤压绘图区
grid
:
{
top
:
"34%"
,
right
:
"3%"
,
bottom
:
"5%"
,
left
:
"2%"
,
containLabel
:
true
},
tooltip
:
{
trigger
:
"axis"
,
axisPointer
:
{
type
:
"line"
}
},
legend
:
{
top
:
8
,
left
:
"center"
,
icon
:
"circle"
,
itemWidth
:
12
,
itemHeight
:
12
,
...
...
@@ -572,6 +602,10 @@ const initRightChart = () => {
const
domains
=
Array
.
from
(
domainsSet
);
const
types
=
Array
.
from
(
typesSet
);
const
legendSplitAt
=
Math
.
ceil
(
types
.
length
/
2
);
const
legendFirstLine
=
types
.
slice
(
0
,
legendSplitAt
);
const
legendSecondLine
=
types
.
slice
(
legendSplitAt
);
const
indicators
=
domains
.
map
((
domain
)
=>
{
const
domainData
=
rawData
.
filter
((
item
)
=>
item
.
AREA
===
domain
);
const
maxVal
=
Math
.
max
(...
domainData
.
map
((
d
)
=>
d
.
COOPERTYPECOUNT
),
5
);
...
...
@@ -589,15 +623,21 @@ const initRightChart = () => {
name
:
type
,
value
:
dataValues
,
itemStyle
:
{
color
:
colorMap
[
index
%
colorMap
.
length
]
},
//
不要填充多边形:让雷达图“圆里面是空的”
// areaStyle 不设置(或设为 0)可避免穿透同心圆的填充效果
//
雷达图围成区域填充:对应颜色 0.1 透明度
areaStyle
:
{
color
:
colorMap
[
index
%
colorMap
.
length
],
opacity
:
0.1
}
};
});
const
option
=
{
color
:
colorMap
,
legend
:
{
// 避免自动换行导致“第二行不居中”:拆成两行 legend,每行各自居中
legend
:
[
{
show
:
true
,
type
:
"plain"
,
data
:
legendFirstLine
,
top
:
8
,
left
:
"center"
,
icon
:
"circle"
,
itemWidth
:
12
,
itemHeight
:
12
,
...
...
@@ -608,12 +648,31 @@ const initRightChart = () => {
fontFamily
:
"Microsoft YaHei"
,
fontWeight
:
400
,
lineHeight
:
24
}
},
data
:
types
},
{
show
:
legendSecondLine
.
length
>
0
,
type
:
"plain"
,
data
:
legendSecondLine
,
top
:
32
,
left
:
"center"
,
icon
:
"circle"
,
itemWidth
:
12
,
itemHeight
:
12
,
itemGap
:
24
,
textStyle
:
{
color
:
"rgb(95, 101, 108)"
,
fontSize
:
16
,
fontFamily
:
"Microsoft YaHei"
,
fontWeight
:
400
,
lineHeight
:
24
}
}
],
radar
:
{
center
:
[
"50%"
,
"55%"
],
radius
:
"65%"
,
// 对齐左侧折线图(grid top=34%)的“图例到图形”间距:下移雷达中心并略缩半径
center
:
[
"50%"
,
"62%"
],
radius
:
"60%"
,
indicator
:
indicators
,
axisName
:
{
color
:
"rgba(132, 136, 142, 1)"
,
...
...
@@ -688,6 +747,11 @@ onBeforeUnmount(() => {
padding
:
0
;
}
/* 合作限制:下拉项内边距(teleport 到 body,用 :global 生效) */
:global
(
.coop-select-dropdown
.el-select-dropdown__item
)
{
padding
:
0
20px
!
important
;
}
.datasub
{
width
:
1600px
;
height
:
460px
;
...
...
@@ -742,7 +806,7 @@ onBeforeUnmount(() => {
height
:
412px
;
box-sizing
:
border-box
;
position
:
relative
;
padding
:
24px
24px
65
px
24px
;
padding
:
0px
24px
64
px
24px
;
&
.left-main--empty
{
display
:
flex
;
...
...
@@ -770,7 +834,7 @@ onBeforeUnmount(() => {
.left-main-echarts
{
width
:
1015px
;
height
:
3
23
px
;
height
:
3
48
px
;
}
.source
{
...
...
@@ -847,7 +911,7 @@ onBeforeUnmount(() => {
width
:
521px
;
height
:
412px
;
box-sizing
:
border-box
;
padding
:
24
px
24px
64px
24px
;
padding
:
0
px
24px
64px
24px
;
position
:
relative
;
&
.right-main--empty
{
...
...
@@ -874,7 +938,7 @@ onBeforeUnmount(() => {
.right-main-echarts
{
width
:
473px
;
height
:
3
24
px
;
height
:
3
48
px
;
}
.source
{
...
...
src/views/coopRestriction/components/resLib/index.vue
浏览文件 @
094f43e3
...
...
@@ -6,7 +6,8 @@
{{
item
.
name
}}
</div>
</div>
<el-select
v-model=
"sortModel"
placeholder=
"发布时间"
class=
"select"
:teleported=
"true"
placement=
"bottom-start"
<el-select
v-model=
"sortModel"
placeholder=
"发布时间"
class=
"select"
popper-class=
"coop-select-dropdown"
:teleported=
"true"
placement=
"bottom-start"
:popper-options=
"sortPopperOptions"
@
change=
"handleSortChange"
>
<template
#
prefix
>
<img
v-if=
"sortModel !== true"
src=
"@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image down.png"
...
...
@@ -120,8 +121,8 @@ const getMainDataList = async () => {
date
:
item
.
limitDate
,
domain
:
item
.
limitArea
||
[],
type
:
item
.
limitMeans
,
//
使用默认图片
img
:
defaultImg
//
优先使用接口返回的机构 logo(limitOrgLogo),空则回退默认图
img
:
item
.
limitOrgLogo
||
defaultImg
}));
total
.
value
=
res
.
data
.
totalElements
||
0
;
}
else
{
...
...
@@ -138,10 +139,16 @@ const getMainDataList = async () => {
const
router
=
useRouter
();
const
handleClick
=
item
=>
{
const
id
=
item
?.
id
||
item
?.
limitId
||
item
?.
ID
;
if
(
!
id
)
return
;
window
.
sessionStorage
.
setItem
(
"cooperationRestrictionsTabName"
,
item
?.
limitName
||
item
?.
title
||
item
?.
name
||
""
);
const
routeData
=
router
.
resolve
({
path
:
"/cooperationRestrictions/d
etail"
,
name
:
"CooperationRestrictionsD
etail"
,
query
:
{
id
:
item
.
id
id
}
});
window
.
open
(
routeData
.
href
,
"_blank"
);
...
...
@@ -355,6 +362,11 @@ watch(currentPage, () => {
padding
:
0
;
}
/* 合作限制:下拉项内边距(teleport 到 body,用 :global 生效) */
:global
(
.coop-select-dropdown
.el-select-dropdown__item
)
{
padding
:
0
20px
!
important
;
}
.reslib-page
{
width
:
1600px
;
...
...
src/views/coopRestriction/detail/index.vue
浏览文件 @
094f43e3
...
...
@@ -45,9 +45,9 @@
<AnalysisBox
title=
"相关实体"
:showAllBtn=
"true"
>
<div
class=
"left-bottom-main"
>
<div
v-for=
"item in coopRelatedData"
:key=
"item.id"
class=
"main-box"
@
click=
"handleClickOnEntity(item)"
>
<img
:src=
"item.img || defaultCom"
alt=
""
/>
<img
:src=
"item.img || defaultCom"
alt=
""
class=
"img-left-item"
/>
<div
class=
"name"
>
{{
item
.
ENTITYNAME
}}
</div>
<div
class=
"type"
>
{{
item
.
type
}}
</div>
<div
class=
"type"
>
{{
item
.
position
}}
</div>
</div>
</div>
</AnalysisBox>
...
...
@@ -80,8 +80,15 @@
<span>
(
{{
chineseNumbers
[
index
]
}}
)
{{
item
.
TITLE
}}
</span>
<img
src=
"./assets/打开按钮.png"
alt=
""
>
</div>
<div
class=
"clause-item-content"
>
{{
item
.
CONTENT
}}
<!-- contentList:单条按原样式展示;多条则逐条展示并加 1.2.3. 前缀 -->
<div
v-if=
"Array.isArray(item.contentList) && item.contentList.length > 1"
class=
"clause-item-content-list"
>
<div
v-for=
"(row, i) in item.contentList"
:key=
"i"
class=
"clause-item-content-row"
>
<span
class=
"row-index"
>
{{
i
+
1
}}
.
</span>
<span
class=
"row-text"
>
{{
row
.
CONTENT
}}
</span>
</div>
</div>
<div
v-else
class=
"clause-item-content-row"
>
<span
class=
"row-text"
>
{{
item
.
contentList
?.[
0
]?.
CONTENT
||
""
}}
</span>
</div>
</div>
</div>
...
...
@@ -163,19 +170,34 @@ const getcoopRelatedData = async () => {
limitId
:
route
.
query
.
id
});
if
(
res
&&
res
.
code
===
200
)
{
coopRelatedData
.
value
=
res
.
data
||
{};
// 展示图片:优先后端返回的 imageUrl,其次用已有 img 字段,再兜底默认图
coopRelatedData
.
value
=
(
Array
.
isArray
(
res
.
data
)
?
res
.
data
:
[]).
map
((
row
)
=>
({
...
row
,
img
:
row
?.
imageUrl
||
row
?.
img
||
row
?.
IMAGEURL
||
row
?.
image
||
""
}));
}
else
{
coopRelatedData
.
value
=
{}
;
coopRelatedData
.
value
=
[]
;
}
}
catch
(
error
)
{
console
.
error
(
"获取合作限制相关实体数据失败:"
,
error
);
coopRelatedData
.
value
=
{}
;
coopRelatedData
.
value
=
[]
;
}
};
// 点击跳转关联实体详情
const
handleClickOnEntity
=
(
item
)
=>
{
if
(
!
item
.
ENTITYID
)
return
;
const
path
=
`/companyPages/
${
item
.
ENTITYID
}
`
;
const
entityType
=
item
?.
ENTITYTYPE
;
// ENTITYTYPE: 'O' 机构/公司;'P' 人物
if
(
entityType
===
"P"
)
{
const
personId
=
item
?.
PERSONID
||
item
?.
ENTITYID
||
item
?.
id
;
if
(
!
personId
)
return
;
const
url
=
`http://localhost:3000/characterPage?type=2&personId=
${
encodeURIComponent
(
personId
)}
`
;
window
.
open
(
url
,
"_blank"
);
return
;
}
// 默认按公司/机构跳转(含 ENTITYTYPE === 'O' 或字段缺失)
const
companyId
=
item
?.
ENTITYID
||
item
?.
id
;
if
(
!
companyId
)
return
;
const
path
=
`/companyPages/
${
companyId
}
`
;
const
{
href
}
=
router
.
resolve
({
path
});
window
.
open
(
href
,
"_blank"
);
};
...
...
@@ -260,11 +282,21 @@ const filteredBackgroundList = computed(() => {
const
active2
=
ref
(
"涉华条款"
);
const
chineseNumbers
=
[
"一"
,
"二"
,
"三"
,
"四"
,
"五"
,
"六"
,
"七"
,
"八"
,
"九"
,
"十"
];
const
filteredClauseList
=
computed
(()
=>
{
const
list
=
Array
.
isArray
(
limitClauseData
.
value
)
?
limitClauseData
.
value
:
[];
if
(
active2
.
value
===
"全部条款"
)
{
return
limitClauseData
.
value
;
}
else
{
return
limitClauseData
.
value
.
filter
(
item
=>
item
.
ISCN
===
"Y"
);
}
// 展示全部条款及全部段落
return
list
.
map
((
item
)
=>
({
...
item
,
contentList
:
Array
.
isArray
(
item
?.
contentList
)
?
item
.
contentList
:
[]
}));
}
// 涉华条款:仅展示 contentList 中 ISCN=Y 的段落;若过滤后为空则不展示该条款
return
list
.
map
((
item
)
=>
{
const
contentList
=
(
Array
.
isArray
(
item
?.
contentList
)
?
item
.
contentList
:
[]).
filter
((
row
)
=>
row
?.
ISCN
===
"Y"
);
return
{
...
item
,
contentList
};
})
.
filter
((
item
)
=>
Array
.
isArray
(
item
?.
contentList
)
&&
item
.
contentList
.
length
>
0
);
});
const
dataList
=
ref
([
...
...
@@ -660,6 +692,12 @@ const dataList3 = ref([
img
{
width
:
24px
;
height
:
24px
;
border-radius
:
50%
;
display
:
inline-block
;
object-fit
:
cover
;
object-position
:
center
;
}
.name
{
...
...
@@ -923,7 +961,12 @@ const dataList3 = ref([
}
}
.clause-item-content
{
.clause-item-content-list
{
width
:
1022px
;
}
/* 每条段落的展示:padding / 描边 / 间距保持与旧版单条 CONTENT 一致 */
.clause-item-content-row
{
width
:
1022px
;
padding
:
12px
24px
12px
54px
;
font-size
:
16px
;
...
...
@@ -933,6 +976,17 @@ const dataList3 = ref([
color
:
rgb
(
59
,
65
,
75
);
border-bottom
:
1px
solid
rgb
(
234
,
236
,
238
);
white-space
:
pre-line
;
display
:
flex
;
gap
:
8px
;
.row-index
{
flex
:
0
0
auto
;
}
.row-text
{
flex
:
1
;
min-width
:
0
;
}
}
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论