Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
b16fe10d
提交
b16fe10d
authored
3月 19, 2026
作者:
张伊明
浏览文件
操作
浏览文件
下载
差异文件
合并分支 'zy-dev' 到 'master'
从 zy-dev 合并到 master 查看合并请求
!187
上级
3dea68fc
3042de15
显示空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
542 行增加
和
1526 行删除
+542
-1526
App.vue
src/App.vue
+14
-0
home.js
src/api/decree/home.js
+3
-3
decree.js
src/router/modules/decree.js
+1
-1
index.vue
src/views/decree/decreeHome/index.vue
+116
-230
index.vue
src/views/decree/decreeLayout/deepdig/index.vue
+2
-1
index.vue
src/views/decree/decreeLayout/index.vue
+32
-86
ChartRelation.vue
src/views/decree/decreeLayout/influence/ChartRelation.vue
+0
-697
AiTips.vue
src/views/decree/decreeLayout/influence/com/AiTips.vue
+62
-0
ChartChain.vue
src/views/decree/decreeLayout/influence/com/ChartChain.vue
+107
-205
index.vue
src/views/decree/decreeLayout/influence/index.vue
+56
-178
index.vue
src/views/decree/decreeLayout/overview/background/index.vue
+32
-12
index.vue
...views/decree/decreeLayout/overview/introduction/index.vue
+11
-18
index.vue
src/views/decree/decreeLayout/overview/measures/index.vue
+105
-93
download.png
src/views/decree/decreeOriginal/assets/icons/download.png
+0
-0
search.png
src/views/decree/decreeOriginal/assets/icons/search.png
+0
-0
index.vue
src/views/decree/decreeOriginal/index.vue
+0
-1
vite.config.js
vite.config.js
+1
-1
没有找到文件。
src/App.vue
浏览文件 @
b16fe10d
...
@@ -235,12 +235,26 @@ body {
...
@@ -235,12 +235,26 @@ body {
display
:
none
;
display
:
none
;
}
}
/* #region 公共样式类名 */
/* 单行文本溢出隐藏显示省略号 */
/* 单行文本溢出隐藏显示省略号 */
.one-line-ellipsis
{
.one-line-ellipsis
{
overflow
:
hidden
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
white-space
:
nowrap
;
}
}
/* 多行文本两端对齐 最后一行正常显示 */
.text-align-justify
{
text-align
:
justify
;
text-align-last
:
left
;
-webkit-text-align-last
:
left
;
}
/* 可点击文本 鼠标悬浮样式 */
#app
.text-click-hover
:hover
{
text-decoration
:
underline
;
color
:
rgb
(
5
,
95
,
194
);
cursor
:
pointer
;
}
/* #endregion 公共样式类名 */
</
style
>
</
style
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
...
...
src/api/decree/home.js
浏览文件 @
b16fe10d
import
request
from
"@/api/request.js"
;
import
request
from
"@/api/request.js"
;
// 最新科技政令
// 最新科技政令
export
function
getDepartmentList
()
{
export
function
getDepartmentList
(
params
)
{
return
request
({
return
request
({
method
:
'GET'
,
method
:
'GET'
,
url
:
`/api/administrativeDict/department`
,
url
:
`/api/administrativeDict/department`
,
...
@@ -43,10 +43,10 @@ export function getDecreeArea(params) {
...
@@ -43,10 +43,10 @@ export function getDecreeArea(params) {
}
}
// 关键行政令
// 关键行政令
export
function
getKeyDecree
()
{
export
function
getKeyDecree
(
params
)
{
return
request
({
return
request
({
method
:
'GET'
,
method
:
'GET'
,
url
:
`/api/administrativeOrderOverview/action`
,
url
:
`/api/administrativeOrderOverview/action
?pageSize=
${
params
.
pageSize
}
&pageNum=
${
params
.
pageNum
}
`
,
})
})
}
}
...
...
src/router/modules/decree.js
浏览文件 @
b16fe10d
...
@@ -18,7 +18,7 @@ const decreeRoutes = [
...
@@ -18,7 +18,7 @@ const decreeRoutes = [
name
:
"Decree"
,
name
:
"Decree"
,
component
:
Decree
,
component
:
Decree
,
meta
:
{
meta
:
{
title
:
"
政令概览
"
title
:
"
科技政令概况
"
}
}
},
},
{
{
...
...
src/views/decree/decreeHome/index.vue
浏览文件 @
b16fe10d
...
@@ -63,12 +63,18 @@
...
@@ -63,12 +63,18 @@
</div>
</div>
</div>
</div>
</div>
-->
</div>
-->
<div
class=
"home-main-header-item-box"
>
<div
class=
"home-main-header-item-box"
v-if=
"govInsList.length"
>
<div
class=
"item"
v-for=
"(item, index) in govInsList"
:key=
"index"
@
click=
"handleToInstitution(item)"
>
<div
class=
"item"
v-for=
"(item, index) in govInsList
.slice(0, 7)
"
:key=
"index"
@
click=
"handleToInstitution(item)"
>
<div
class=
"item-left"
>
<div
class=
"item-left"
>
<img
:src=
"item.img ? item.img : DefaultIcon2"
alt=
""
/>
<img
:src=
"item.orgImage || DefaultIcon2"
alt=
""
/>
</div>
<div
class=
"item-right one-line-ellipsis"
>
{{
item
.
orgName
}}
</div>
<div
class=
"item-num"
>
{{
item
.
total
}}
项
</div>
<el-icon
color=
"var(--color-primary-100)"
><ArrowRightBold
/></el-icon>
</div>
</div>
<div
class=
"item-right"
>
{{
item
.
name
}}
</div>
<div
class=
"item"
>
<div
class=
"item-num item-more"
>
查看全部机构 (
{{
govInsList
.
length
+
1
}}
家)
</div>
<el-icon
color=
"var(--color-primary-100)"
><ArrowRightBold
/></el-icon>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -115,15 +121,7 @@
...
@@ -115,15 +121,7 @@
{{
item
.
name
}}
{{
item
.
name
}}
</div>
</div>
<div
class=
"box1-main-right-info"
>
<div
class=
"box1-main-right-info"
>
<!--
<div
class=
"tag"
:class=
"
{
<AreaTag
v-for=
"(tag, index) in item.industryList"
:key=
"index"
:tagName=
"tag.industryName"
/>
tag1: tag.status == 1,
tag2: tag.status == 2,
tag3: tag.status == 3
}" v-for="(tag, index) in item.industryList" :key="index">
{{
tag
.
industryName
}}
</div>
-->
<AreaTag
v-for=
"(tag, index) in item.industryList"
:key=
"index"
:tagName=
"tag.industryName"
>
</AreaTag>
</div>
</div>
<div
class=
"box1-main-right-center"
>
<div
class=
"box1-main-right-center"
>
{{
item
.
describe
}}
{{
item
.
describe
}}
...
@@ -243,6 +241,7 @@
...
@@ -243,6 +241,7 @@
<div
class=
"header-title"
>
{{
"关键行政令"
}}
</div>
<div
class=
"header-title"
>
{{
"关键行政令"
}}
</div>
</div>
</div>
<div
class=
"box7-main"
>
<div
class=
"box7-main"
>
<div
class=
"box7-list"
>
<div
class=
"box7-item"
v-for=
"(item, index) in keyDecreeList"
:key=
"index"
@
click=
"handleKeyDecree(item)"
>
<div
class=
"box7-item"
v-for=
"(item, index) in keyDecreeList"
:key=
"index"
@
click=
"handleKeyDecree(item)"
>
<div
class=
"icon"
>
<div
class=
"icon"
>
<img
src=
"./assets/images/warning.png"
alt=
""
/>
<img
src=
"./assets/images/warning.png"
alt=
""
/>
...
@@ -253,14 +252,11 @@
...
@@ -253,14 +252,11 @@
<div
class=
"time"
>
{{
item
.
time
}}
</div>
<div
class=
"time"
>
{{
item
.
time
}}
</div>
</div>
</div>
<div
class=
"info-content"
>
{{
item
.
content
?
item
.
content
:
"暂无数据"
}}
</div>
<div
class=
"info-content"
>
{{
item
.
content
?
item
.
content
:
"暂无数据"
}}
</div>
<!--
<el-popover
effect=
"dark"
:width=
"800"
:content=
"item.content"
placement=
"top-start"
>
<template
#
reference
>
<div
class=
"info-content"
>
{{
item
.
content
?
item
.
content
:
"暂无数据"
}}
</div>
</
template
>
</el-popover>
-->
</div>
</div>
</div>
</div>
</div>
</div>
<SimplePagination
v-model:current-page=
"keyDecreeInfo.page"
:page-size=
"keyDecreeInfo.size"
:total=
"keyDecreeInfo.total"
@
page-change=
"handleGetKeyDecree"
/>
</div>
</div>
</div>
<div
class=
"box8"
>
<div
class=
"box8"
>
<div
class=
"box8-header"
>
<div
class=
"box8-header"
>
...
@@ -269,17 +265,19 @@
...
@@ -269,17 +265,19 @@
</div>
</div>
<div
class=
"header-title"
>
{{
"政令重点条款"
}}
</div>
<div
class=
"header-title"
>
{{
"政令重点条款"
}}
</div>
</div>
</div>
<div
class=
"box8-main"
id=
"wordCloudChart"
></div>
<div
class=
"box8-content"
v-if=
"wordCloudData?.length"
>
<WordCloudChart
:data=
"wordCloudData"
width=
"100%"
height=
"100%"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"home-main-footer"
>
<div
class=
"home-main-footer"
>
<DivideHeader
id=
"position4"
class=
"divide4"
:titleText=
"'
资源
库'"
></DivideHeader>
<DivideHeader
id=
"position4"
class=
"divide4"
:titleText=
"'
科技政令
库'"
></DivideHeader>
<div
class=
"home-main-footer-header"
>
<div
class=
"home-main-footer-header"
>
<div
class=
"search-box"
>
<div
class=
"search-box"
>
<el-select
v-model=
"searchType"
:empty-values=
"[null, undefined]"
style=
"width: 100%"
>
<el-select
v-model=
"searchType"
:empty-values=
"[null, undefined]"
style=
"width: 100%"
filterable
>
<el-option
label=
"全部政府部门"
value=
""
/>
<el-option
label=
"全部政府部门"
value=
""
/>
<el-option
v-for=
"item in govInsList"
:key=
"item.
id"
:label=
"item.name"
:value=
"item.i
d"
/>
<el-option
v-for=
"item in govInsList"
:key=
"item.
orgId"
:label=
"item.orgName"
:value=
"item.orgI
d"
/>
</el-select>
</el-select>
</div>
</div>
<div
style=
"flex: auto;"
></div>
<div
style=
"flex: auto;"
></div>
...
@@ -306,38 +304,23 @@
...
@@ -306,38 +304,23 @@
</div>
</div>
<div
class=
"select-main"
>
<div
class=
"select-main"
>
<div
class=
"checkbox-group"
>
<div
class=
"checkbox-group"
>
<el-checkbox
v-for=
"type in decreeTypeList"
:key=
"type.id"
v-model=
"checkedDecreeType"
<el-checkbox
v-for=
"type in decreeTypeList"
:key=
"type.id"
v-model=
"checkedDecreeType"
:label=
"type.typeId"
:label=
"type.typeId"
style=
"width: 180px"
class=
"filter-checkbox"
style=
"width: 180px"
class=
"filter-checkbox"
@
change=
"handleChangeCheckedDecreeType"
>
@
change=
"handleChangeCheckedDecreeType"
>
{{ type.typeName }}
{{ type.typeName }}
</el-checkbox>
</el-checkbox>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div class="select-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "发布机构" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox v-for="cate in govInsList" :key="cate.id" v-model="checkedGovIns"
:label="cate.id" style="width: 180px" class="filter-checkbox"
@change="handleChangeCheckedGovIns">
{{ cate.name }}
</el-checkbox>
</div>
</div>
</div> -->
<div
class=
"select-box"
>
<div
class=
"select-box"
>
<div
class=
"select-box-header"
>
<div
class=
"select-box-header"
>
<div
class=
"icon"
></div>
<div
class=
"icon"
></div>
<div
class=
"title"
>
{{ "科技领域" }}
</div>
<div
class=
"title"
>
{{ "科技领域" }}
</div>
</div>
</div>
<div
class=
"select-main
select-main1
"
>
<div
class=
"select-main"
>
<div
class=
"checkbox-group"
>
<div
class=
"checkbox-group"
>
<el-checkbox
v-for=
"area in areaList"
:key=
"area.id"
v-model=
"activeAreaList"
:label=
"area.id"
<el-checkbox
v-for=
"area in areaList"
:key=
"area.id"
v-model=
"activeAreaList"
:label=
"area.id"
style=
"width: 100px"
@
change=
"checked => handleAreaChange(area.id, checked)"
>
style=
"width: 100px"
class=
"filter-checkbox"
@
change=
"checked => handleAreaChange(area.id, checked)"
>
{{ area.name }}
{{ area.name }}
</el-checkbox>
</el-checkbox>
</div>
</div>
...
@@ -351,28 +334,12 @@
...
@@ -351,28 +334,12 @@
<div
class=
"select-main"
>
<div
class=
"select-main"
>
<div
class=
"checkbox-group"
>
<div
class=
"checkbox-group"
>
<el-checkbox
v-for=
"time in pubTime"
:key=
"time.id"
v-model=
"activePubTime"
:label=
"time.id"
<el-checkbox
v-for=
"time in pubTime"
:key=
"time.id"
v-model=
"activePubTime"
:label=
"time.id"
style=
"width: 100px"
class=
"filter-checkbox"
style=
"width: 100px"
class=
"filter-checkbox"
@
change=
"checked => handlePubTimeChange(time.id, checked)"
>
@
change=
"checked => handlePubTimeChange(time.id, checked)"
>
{{ time.name }}
{{ time.name }}
</el-checkbox>
</el-checkbox>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div class="select-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "涉及领域" }}</div>
</div>
<div class="select-main select-main1">
<div class="checkbox-group">
<el-checkbox v-for="area in areaList" :key="area.id" v-model="activeAreaList"
:label="area.id" style="width: 100px"
@change="checked => handleAreaChange(area.id, checked)">
{{ area.name }}
</el-checkbox>
</div>
</div>
</div> -->
</div>
</div>
<div
class=
"right"
>
<div
class=
"right"
>
<div
class=
"content-header"
>
<div
class=
"content-header"
>
...
@@ -403,9 +370,7 @@
...
@@ -403,9 +370,7 @@
</div>
</div>
<div
class=
"desc"
>
{{ item.desc }}
</div>
<div
class=
"desc"
>
{{ item.desc }}
</div>
<div
class=
"tag-box"
>
<div
class=
"tag-box"
>
<div
class=
"tag"
v-for=
"(val, idx) in item.tagList"
:key=
"idx"
>
<AreaTag
v-for=
"(tag, index) in item.tagList"
:key=
"index"
:tagName=
"tag.industryName"
/>
{{ val.industryName }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -427,9 +392,10 @@
...
@@ -427,9 +392,10 @@
</template>
</template>
<
script
setup
>
<
script
setup
>
import
NewsList
from
"@/components/base/NewsList/index.vue"
;
import
{
onMounted
,
ref
,
watch
,
nextTick
,
reactive
}
from
"vue"
;
import
{
onMounted
,
ref
,
watch
,
nextTick
}
from
"vue"
;
import
router
from
"@/router"
;
import
router
from
"@/router"
;
import
WordCloudChart
from
"@/components/base/WordCloundChart/index.vue"
import
SimplePagination
from
"@/components/SimplePagination.vue"
;
import
{
import
{
getDepartmentList
,
getDepartmentList
,
getLatestDecree
,
getLatestDecree
,
...
@@ -448,7 +414,6 @@ import DivideHeader from "@/components/DivideHeader.vue";
...
@@ -448,7 +414,6 @@ import DivideHeader from "@/components/DivideHeader.vue";
import
{
useContainerScroll
}
from
"@/hooks/useScrollShow"
;
import
{
useContainerScroll
}
from
"@/hooks/useScrollShow"
;
import
getBarChart
from
"./utils/barChart"
;
import
getBarChart
from
"./utils/barChart"
;
import
getPieChart
from
"./utils/piechart"
;
import
getPieChart
from
"./utils/piechart"
;
import
getWordCloudChart
from
"./utils/wordCloudChart"
;
import
setChart
from
"@/utils/setChart"
;
import
setChart
from
"@/utils/setChart"
;
...
@@ -458,11 +423,11 @@ import { ElMessage } from "element-plus";
...
@@ -458,11 +423,11 @@ import { ElMessage } from "element-plus";
// 跳转行政机构主页
// 跳转行政机构主页
const
handleToInstitution
=
item
=>
{
const
handleToInstitution
=
item
=>
{
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
n
ame
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
orgN
ame
);
const
curRoute
=
router
.
resolve
({
const
curRoute
=
router
.
resolve
({
path
:
"/institution"
,
path
:
"/institution"
,
query
:
{
query
:
{
id
:
item
.
i
d
id
:
item
.
orgI
d
}
}
});
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
window
.
open
(
curRoute
.
href
,
"_blank"
);
...
@@ -480,32 +445,15 @@ const handleCurrentChange = page => {
...
@@ -480,32 +445,15 @@ const handleCurrentChange = page => {
};
};
// 页面 header
// 页面 header
const
govInsList
=
ref
([
const
govInsList
=
ref
([]);
// {
// img: Gov1,
// name: "美国白宫"
// },
// {
// img: Gov2,
// name: "美国财政部"
// },
]);
const
checkedGovIns
=
ref
([]);
const
checkedGovIns
=
ref
([]);
const
handleChangeCheckedGovIns
=
val
=>
{
};
const
handleGetDepartmentList
=
async
()
=>
{
const
handleGetDepartmentList
=
async
()
=>
{
try
{
try
{
const
res
=
await
getDepartmentList
();
const
res
=
await
getDepartmentList
();
console
.
log
(
"机构列表"
,
res
);
console
.
log
(
"机构列表"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
if
(
res
.
code
===
200
&&
res
.
data
)
{
govInsList
.
value
=
res
.
data
.
map
(
item
=>
{
govInsList
.
value
=
res
.
data
;
return
{
id
:
item
.
orgId
,
name
:
item
.
orgName
,
img
:
item
.
orgImage
};
});
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
"获取机构列表error"
,
error
);
console
.
error
(
"获取机构列表error"
,
error
);
...
@@ -649,11 +597,8 @@ const newsList = ref([
...
@@ -649,11 +597,8 @@ const newsList = ref([
// }
// }
]);
]);
const
handleGetNews
=
async
()
=>
{
const
handleGetNews
=
async
()
=>
{
const
params
=
{
moduleId
:
"0101"
};
try
{
try
{
const
res
=
await
getNews
(
params
);
const
res
=
await
getNews
(
{
moduleId
:
"0101"
}
);
console
.
log
(
"新闻资讯"
,
res
);
console
.
log
(
"新闻资讯"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
if
(
res
.
code
===
200
&&
res
.
data
)
{
// newsList.value = res.data || []
// newsList.value = res.data || []
...
@@ -671,7 +616,6 @@ const handleGetNews = async () => {
...
@@ -671,7 +616,6 @@ const handleGetNews = async () => {
console
.
error
(
"新闻资讯error"
,
error
);
console
.
error
(
"新闻资讯error"
,
error
);
}
}
};
};
handleGetNews
();
// 点击新闻条目,跳转到新闻分析页
// 点击新闻条目,跳转到新闻分析页
const
handleToNewsAnalysis
=
news
=>
{
const
handleToNewsAnalysis
=
news
=>
{
const
route
=
router
.
resolve
({
const
route
=
router
.
resolve
({
...
@@ -914,13 +858,19 @@ const handleBox6YearChange = () => {
...
@@ -914,13 +858,19 @@ const handleBox6YearChange = () => {
// 关键行政令
// 关键行政令
const
keyDecreeList
=
ref
([]);
const
keyDecreeList
=
ref
([]);
const
keyDecreeInfo
=
reactive
({
total
:
0
,
page
:
1
,
size
:
3
,
})
const
handleGetKeyDecree
=
async
()
=>
{
const
handleGetKeyDecree
=
async
()
=>
{
try
{
try
{
const
res
=
await
getKeyDecree
();
const
res
=
await
getKeyDecree
(
{
pageSize
:
keyDecreeInfo
.
size
,
pageNum
:
keyDecreeInfo
.
page
-
1
}
);
console
.
log
(
"关键行政令"
,
res
);
console
.
log
(
"关键行政令"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
if
(
res
.
code
===
200
&&
res
.
data
?.
total
)
{
keyDecreeList
.
value
=
res
.
data
.
map
(
item
=>
{
keyDecreeInfo
.
total
=
res
.
data
.
total
||
0
;
keyDecreeList
.
value
=
res
.
data
.
list
.
map
(
item
=>
{
return
{
return
{
title
:
item
.
name
,
title
:
item
.
name
,
content
:
item
.
describe
,
content
:
item
.
describe
,
...
@@ -935,38 +885,17 @@ const handleGetKeyDecree = async () => {
...
@@ -935,38 +885,17 @@ const handleGetKeyDecree = async () => {
handleGetKeyDecree
();
handleGetKeyDecree
();
// 政令重点条款
// 政令重点条款
const
wordCloudData
=
[
const
wordCloudData
=
ref
([]);
// { name: "与马斯克公开冲突", value: 100 },
// { name: "传统能源", value: 5 },
// { name: "共和党财政鹰派", value: 77 },
// { name: "未实现赤字控制目标", value: 35 },
// { name: "得克萨斯州", value: 88 },
// { name: "选举压力", value: 57 },
// { name: "主张财政紧缩", value: 72 },
// { name: "财政保守", value: 18 },
];
const
handleGetDecreeKeyInstruction
=
async
()
=>
{
const
handleGetDecreeKeyInstruction
=
async
()
=>
{
try
{
try
{
const
res
=
await
getDecreeKeyInstruction
();
const
res
=
await
getDecreeKeyInstruction
();
console
.
log
(
"政令重点条款"
,
res
);
console
.
log
(
"政令重点条款"
,
res
);
wordCloudData
.
value
=
res
.
data
.
map
(
item
=>
{
wordCloudData
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
clause
,
value
:
item
.
count
}));
return
{
name
:
item
.
clause
,
value
:
item
.
count
};
});
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
"政令重点条款error"
,
error
);
console
.
error
(
"政令重点条款error"
,
error
);
}
}
};
};
const
handleBox8
=
async
()
=>
{
await
handleGetDecreeKeyInstruction
();
let
chart3
=
getWordCloudChart
(
wordCloudData
.
value
);
setChart
(
chart3
,
"wordCloudChart"
);
};
// 资源库
// 资源库
const
searchType
=
ref
(
""
);
const
searchType
=
ref
(
""
);
const
isChina
=
ref
(
false
);
const
isChina
=
ref
(
false
);
...
@@ -995,22 +924,6 @@ const handleToPosi = id => {
...
@@ -995,22 +924,6 @@ const handleToPosi = id => {
}
}
};
};
// const handleGetAreaList = async () => {
// try {
// const res = await getDecreehylyList();
// console.log("行业领域列表", res);
// if (res.code === 200 && res.data) {
// areaList.value = res.data.map(item => {
// return {
// name: item.name,
// id: item.id
// };
// });
// console.log("areaList", areaList.value);
// }
// } catch (error) { }
// };
// 政令类型
// 政令类型
const
decreeTypeList
=
ref
([]);
const
decreeTypeList
=
ref
([]);
const
checkedDecreeType
=
ref
([]);
const
checkedDecreeType
=
ref
([]);
...
@@ -1101,7 +1014,7 @@ const handleGetAreaList = async () => {
...
@@ -1101,7 +1014,7 @@ const handleGetAreaList = async () => {
console
.
log
(
"行业领域列表"
,
res
);
console
.
log
(
"行业领域列表"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
if
(
res
.
code
===
200
&&
res
.
data
)
{
areaList
.
value
=
[
areaList
.
value
=
[
{
name
:
"全
选
"
,
id
:
"all"
},
{
name
:
"全
部领域
"
,
id
:
"all"
},
...
res
.
data
.
map
(
item
=>
{
...
res
.
data
.
map
(
item
=>
{
return
{
return
{
name
:
item
.
name
,
name
:
item
.
name
,
...
@@ -1218,13 +1131,14 @@ const handleSearch = () => {
...
@@ -1218,13 +1131,14 @@ const handleSearch = () => {
};
};
onMounted
(
async
()
=>
{
onMounted
(
async
()
=>
{
handleGetNews
();
handleGetDecreeTypeList
();
handleGetDecreeTypeList
();
handleGetAreaList
();
handleGetAreaList
();
handleGetDecreeOrderList
();
handleGetDecreeOrderList
();
handleBox1
();
// 最新科技政令
handleBox1
();
// 最新科技政令
handleBox5
();
handleBox5
();
handleBox6
();
handleBox6
();
handle
Box8
();
handle
GetDecreeKeyInstruction
();
});
});
</
script
>
</
script
>
...
@@ -1476,15 +1390,17 @@ onMounted(async () => {
...
@@ -1476,15 +1390,17 @@ onMounted(async () => {
}
}
.home-main-header-item-box
{
.home-main-header-item-box
{
margin-top
:
48px
;
margin
:
48px
0
64px
;
margin-bottom
:
64px
;
width
:
1600px
;
width
:
1600px
;
display
:
flex
;
display
:
flex
;
flex-wrap
:
wrap
;
flex-wrap
:
wrap
;
gap
:
16px
;
.item
{
.item
{
width
:
254px
;
width
:
20%
;
height
:
72px
;
flex
:
auto
;
height
:
80px
;
padding
:
0
16px
;
display
:
flex
;
display
:
flex
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
background
:
rgba
(
255
,
255
,
255
,
0
.65
);
background
:
rgba
(
255
,
255
,
255
,
0
.65
);
...
@@ -1492,8 +1408,7 @@ onMounted(async () => {
...
@@ -1492,8 +1408,7 @@ onMounted(async () => {
border-radius
:
10px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
align-items
:
center
;
align-items
:
center
;
gap
:
17px
;
justify-content
:
center
;
margin
:
0
6px
16px
6px
;
cursor
:
pointer
;
cursor
:
pointer
;
transition
:
transition
:
transform
0
.3s
ease
,
transform
0
.3s
ease
,
...
@@ -1505,10 +1420,9 @@ onMounted(async () => {
...
@@ -1505,10 +1420,9 @@ onMounted(async () => {
}
}
.item-left
{
.item-left
{
margin-left
:
24px
;
width
:
48px
;
width
:
48px
;
height
:
48px
;
height
:
48px
;
font-size
:
0px
;
img
{
img
{
width
:
100%
;
width
:
100%
;
height
:
100%
;
height
:
100%
;
...
@@ -1516,12 +1430,28 @@ onMounted(async () => {
...
@@ -1516,12 +1430,28 @@ onMounted(async () => {
}
}
.item-right
{
.item-right
{
width
:
140px
;
width
:
20px
;
flex
:
auto
;
color
:
rgba
(
59
,
65
,
75
,
1
);
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
font-size
:
20px
;
font-weight
:
700
;
font-weight
:
700
;
line-height
:
24px
;
line-height
:
20px
;
margin
:
0
16px
;
}
.item-num
{
white-space
:
nowrap
;
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
font-weight
:
700
;
line-height
:
20px
;
margin-right
:
2px
;
color
:
var
(
--
color-primary-100
);
}
.item-more
{
margin-right
:
12px
;
font-size
:
16px
;
}
}
}
}
}
}
...
@@ -1708,15 +1638,10 @@ onMounted(async () => {
...
@@ -1708,15 +1638,10 @@ onMounted(async () => {
line-height
:
26px
;
line-height
:
26px
;
display
:
-
webkit-box
;
display
:
-
webkit-box
;
/* 将元素设置为弹性盒模型 */
-webkit-line-clamp
:
2
;
-webkit-line-clamp
:
2
;
/* 限制文本显示的行数 */
-webkit-box-orient
:
vertical
;
-webkit-box-orient
:
vertical
;
/* 设置弹性盒子的子元素垂直排列 */
overflow
:
hidden
;
overflow
:
hidden
;
/* 隐藏溢出的内容 */
text-overflow
:
ellipsis
;
text-overflow
:
ellipsis
;
/* 文本溢出时显示省略号 */
}
}
.box1-main-right-info
{
.box1-main-right-info
{
...
@@ -1724,58 +1649,21 @@ onMounted(async () => {
...
@@ -1724,58 +1649,21 @@ onMounted(async () => {
display
:
flex
;
display
:
flex
;
height
:
24px
;
height
:
24px
;
gap
:
8px
;
gap
:
8px
;
.tag
{
height
:
24px
;
line-height
:
24px
;
padding
:
0
8px
;
box-sizing
:
border-box
;
border-radius
:
4px
;
margin-right
:
5px
;
border
:
1px
solid
rgba
(
255
,
163
,
158
,
1
);
color
:
rgba
(
245
,
34
,
45
,
1
);
background
:
rgba
(
255
,
241
,
240
,
1
);
}
.tag1
{
border
:
1px
solid
rgba
(
135
,
232
,
222
,
1
);
color
:
rgba
(
19
,
168
,
168
,
1
);
background
:
rgba
(
230
,
255
,
251
,
1
);
}
.tag2
{
border
:
1px
solid
rgba
(
186
,
224
,
255
,
1
);
background
:
rgba
(
230
,
244
,
255
,
1
);
color
:
rgba
(
22
,
119
,
255
,
1
);
}
.tag3
{
border
:
1px
solid
rgba
(
255
,
229
,
143
,
1
);
color
:
rgba
(
250
,
173
,
20
,
1
);
background
:
rgba
(
255
,
251
,
230
,
1
);
}
.tag4
{
border
:
1px
solid
rgba
(
255
,
163
,
158
,
1
);
color
:
rgba
(
245
,
34
,
45
,
1
);
background
:
rgba
(
255
,
241
,
240
,
1
);
}
}
}
.box1-main-right-center
{
.box1-main-right-center
{
margin-top
:
10px
;
margin-top
:
10px
;
height
:
20
0px
;
height
:
18
0px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-size
:
16px
;
font-weight
:
400
;
font-weight
:
400
;
line-height
:
30px
;
line-height
:
30px
;
display
:
-
webkit-box
;
display
:
-
webkit-box
;
/* 将元素设置为弹性盒模型 */
-webkit-line-clamp
:
6
;
-webkit-box-orient
:
vertical
;
overflow
:
hidden
;
overflow
:
hidden
;
/* 隐藏溢出的内容 */
text-overflow
:
ellipsis
;
text-overflow
:
ellipsis
;
/* 文本溢出时显示省略号 */
}
}
.box1-main-right-footer
{
.box1-main-right-footer
{
...
@@ -2730,15 +2618,6 @@ onMounted(async () => {
...
@@ -2730,15 +2618,6 @@ onMounted(async () => {
font-weight
:
400
;
font-weight
:
400
;
}
}
}
}
.info-content
{
margin-top
:
3px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
}
}
}
}
}
}
}
...
@@ -2912,10 +2791,9 @@ onMounted(async () => {
...
@@ -2912,10 +2791,9 @@ onMounted(async () => {
.box7-main
{
.box7-main
{
margin-top
:
10px
;
margin-top
:
10px
;
height
:
380px
;
box-sizing
:
border-box
;
.box7-list
{
overflow-y
:
auto
;
height
:
310px
;
overflow-x
:
hidden
;
.box7-item
{
.box7-item
{
width
:
730px
;
width
:
730px
;
...
@@ -2985,7 +2863,12 @@ onMounted(async () => {
...
@@ -2985,7 +2863,12 @@ onMounted(async () => {
font-size
:
16px
;
font-size
:
16px
;
font-weight
:
400
;
font-weight
:
400
;
line-height
:
24px
;
line-height
:
24px
;
display
:
-
webkit-box
;
-webkit-line-clamp
:
2
;
-webkit-box-orient
:
vertical
;
overflow
:
hidden
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
}
}
}
}
}
}
}
...
@@ -2999,9 +2882,11 @@ onMounted(async () => {
...
@@ -2999,9 +2882,11 @@ onMounted(async () => {
border-radius
:
10px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
display
:
flex
;
flex-direction
:
column
;
.box8-header
{
.box8-header
{
width
:
792px
;
width
:
100%
;
height
:
48px
;
height
:
48px
;
display
:
flex
;
display
:
flex
;
border-bottom
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
border-bottom
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
...
@@ -3030,6 +2915,12 @@ onMounted(async () => {
...
@@ -3030,6 +2915,12 @@ onMounted(async () => {
}
}
}
}
.box8-content
{
width
:
100%
;
height
:
20px
;
flex
:
auto
;
}
.box8-main
{
.box8-main
{
height
:
401px
;
height
:
401px
;
}
}
...
@@ -3039,7 +2930,6 @@ onMounted(async () => {
...
@@ -3039,7 +2930,6 @@ onMounted(async () => {
.home-main-footer
{
.home-main-footer
{
margin-top
:
34px
;
margin-top
:
34px
;
max-height
:
1860px
;
padding-bottom
:
160px
;
padding-bottom
:
160px
;
background
:
rgba
(
248
,
249
,
250
,
1
);
background
:
rgba
(
248
,
249
,
250
,
1
);
overflow
:
hidden
;
overflow
:
hidden
;
...
@@ -3133,16 +3023,21 @@ onMounted(async () => {
...
@@ -3133,16 +3023,21 @@ onMounted(async () => {
.left
{
.left
{
width
:
360px
;
width
:
360px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
height
:
100%
;
background
:
rgba
(
255
,
255
,
255
,
1
);
padding-bottom
:
24px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-radius
:
10px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
20px
0px
rgba
(
94
,
95
,
95
,
0
.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
position
:
relative
;
.select-box
{
.select-box
{
margin-top
:
16px
;
margin-top
:
16px
;
.select-box-header
{
.select-box-header
{
display
:
flex
;
display
:
flex
;
gap
:
1
6
px
;
gap
:
1
7
px
;
.icon
{
.icon
{
margin-top
:
4px
;
margin-top
:
4px
;
...
@@ -3155,7 +3050,7 @@ onMounted(async () => {
...
@@ -3155,7 +3050,7 @@ onMounted(async () => {
.title
{
.title
{
height
:
24px
;
height
:
24px
;
color
:
var
(
--
color-main-active
);
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-family
:
"Source Han Sans CN"
;
font-size
:
16px
;
font-size
:
16px
;
font-weight
:
700
;
font-weight
:
700
;
line-height
:
24px
;
line-height
:
24px
;
...
@@ -3165,11 +3060,20 @@ onMounted(async () => {
...
@@ -3165,11 +3060,20 @@ onMounted(async () => {
}
}
.select-main
{
.select-main
{
margin-left
:
2
5
px
;
margin-left
:
2
4
px
;
}
margin-top
:
12px
;
.select-main1
{
.checkbox-group
{
width
:
260px
;
display
:
grid
;
grid-template-columns
:
repeat
(
2
,
160px
);
gap
:
8px
4px
;
.filter-checkbox
{
width
:
160px
;
height
:
24px
;
margin-right
:
0
!
important
;
}
}
}
}
}
}
}
}
...
@@ -3177,7 +3081,6 @@ onMounted(async () => {
...
@@ -3177,7 +3081,6 @@ onMounted(async () => {
.right
{
.right
{
width
:
20px
;
width
:
20px
;
flex
:
auto
;
flex
:
auto
;
max-height
:
1489px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
box-sizing
:
border-box
;
box-sizing
:
border-box
;
...
@@ -3213,12 +3116,9 @@ onMounted(async () => {
...
@@ -3213,12 +3116,9 @@ onMounted(async () => {
}
}
.content-box
{
.content-box
{
max-height
:
1367px
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
overflow
:
hidden
;
overflow
:
hidden
;
min-height
:
790px
;
min-height
:
790px
;
overflow
:
hidden
;
overflow-y
:
auto
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
.main-item
{
.main-item
{
...
@@ -3349,20 +3249,6 @@ onMounted(async () => {
...
@@ -3349,20 +3249,6 @@ onMounted(async () => {
display
:
flex
;
display
:
flex
;
flex-wrap
:
wrap
;
flex-wrap
:
wrap
;
gap
:
8px
;
gap
:
8px
;
.tag
{
height
:
28px
;
line-height
:
28px
;
text-align
:
center
;
padding
:
0
8px
;
border-radius
:
4px
;
background
:
rgba
(
231
,
243
,
255
,
1
);
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
letter-spacing
:
0px
;
}
}
}
}
}
}
}
...
...
src/views/decree/decreeLayout/deepdig/index.vue
浏览文件 @
b16fe10d
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
<div
class=
"box1"
>
<div
class=
"box1"
>
<AnalysisBox
title=
"相关政令"
:showAllBtn=
"false"
>
<AnalysisBox
title=
"相关政令"
:showAllBtn=
"false"
>
<div
class=
"box1-main"
>
<div
class=
"box1-main"
>
<el-empty
v-if=
"
siderList.length===0"
style=
"padding-top: 30%
"
description=
"暂无数据"
:image-size=
"100"
/>
<el-empty
v-if=
"
!siderList?.length"
style=
"padding-top: 40%;
"
description=
"暂无数据"
:image-size=
"100"
/>
<el-scrollbar
height=
"100%"
always
>
<el-scrollbar
height=
"100%"
always
>
<div
class=
"left-item"
:class=
"
{ 'item-active': false }" v-for="(item, index) in siderList" :key="index" @click="handleClickDecree(item)">
<div
class=
"left-item"
:class=
"
{ 'item-active': false }" v-for="(item, index) in siderList" :key="index" @click="handleClickDecree(item)">
<div
class=
"item-head"
>
<div
class=
"item-head"
>
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
</div>
</div>
<div
class=
"box2"
>
<div
class=
"box2"
>
<AnalysisBox
title=
"政令关系挖掘"
:showAllBtn=
"false"
>
<AnalysisBox
title=
"政令关系挖掘"
:showAllBtn=
"false"
>
<el-empty
v-if=
"!siderList?.length"
style=
"padding-top: 20%;"
description=
"暂无数据"
:image-size=
"100"
/>
<div
class=
"box2-main"
>
<div
class=
"box2-main"
>
<div
ref=
"containerRef"
class=
"graph-container"
></div>
<div
ref=
"containerRef"
class=
"graph-container"
></div>
</div>
</div>
...
...
src/views/decree/decreeLayout/index.vue
浏览文件 @
b16fe10d
...
@@ -8,22 +8,16 @@
...
@@ -8,22 +8,16 @@
<div
class=
"layout-main-header-left-box"
>
<div
class=
"layout-main-header-left-box"
>
<div
class=
"left-box-top"
>
<div
class=
"left-box-top"
>
<div
class=
"icon"
>
<div
class=
"icon"
>
<img
<img
:src=
"summaryInfo.imageUrl || USALogo"
alt=
""
/>
v-if=
"summaryInfo.imageUrl"
:src=
"summaryInfo.imageUrl"
alt=
""
style=
"height: 40px; margin-top: 12px"
/>
<img
v-else
:src=
"USALogo"
alt=
""
/>
</div>
</div>
<div
class=
"info"
>
<div
class=
"info"
>
<div
class=
"info-box1
"
>
{{
summaryInfo
.
name
}}
</div>
<div
class=
"info-box1
one-line-ellipsis"
>
{{
summaryInfo
.
name
||
"--"
}}
</div>
<div
class=
"info-box2"
>
<div
class=
"info-box2"
>
<div
class=
"info-box2-item
item1"
>
{{
summaryInfo
.
postDate
}}
</div>
<div
class=
"info-box2-item
"
>
{{
summaryInfo
.
postDate
||
"--"
}}
</div>
|
|
<div
class=
"info-box2-item
item2"
>
{{
summaryInfo
.
orgName
}}
</div>
<div
class=
"info-box2-item
"
>
{{
summaryInfo
.
orgName
||
"--"
}}
</div>
|
|
<div
class=
"info-box2-item
item3"
>
{{
summaryInfo
.
ename
}}
</div>
<div
class=
"info-box2-item
one-line-ellipsis"
>
{{
summaryInfo
.
ename
||
"--"
}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -47,8 +41,8 @@
...
@@ -47,8 +41,8 @@
</div>
</div>
<div
class=
"layout-main-header-right-box"
>
<div
class=
"layout-main-header-right-box"
>
<div
class=
"right-box-top"
>
<div
class=
"right-box-top"
>
<div
class=
"time"
>
{{
summaryInfo
.
postDate
}}
</div>
<div
class=
"time"
>
{{
summaryInfo
.
postDate
||
"--"
}}
</div>
<div
class=
"name"
>
{{
summaryInfo
.
orgName
}}
</div>
<div
class=
"name"
>
{{
summaryInfo
.
orgName
||
"--"
}}
</div>
</div>
</div>
<div
class=
"right-box-bottom"
>
<div
class=
"right-box-bottom"
>
<div
class=
"btn"
@
click=
"handleShowReport"
>
<div
class=
"btn"
@
click=
"handleShowReport"
>
...
@@ -203,12 +197,12 @@ const mainHeaderBtnList = ref([
...
@@ -203,12 +197,12 @@ const mainHeaderBtnList = ref([
name
:
"深度挖掘"
,
name
:
"深度挖掘"
,
path
:
"/decreeLayout/deepDig"
path
:
"/decreeLayout/deepDig"
},
},
//
{
{
//
icon: icon3,
icon
:
icon3
,
//
activeIcon: icon3Active,
activeIcon
:
icon3Active
,
//
name: "影响分析",
name
:
"影响分析"
,
//
path: "/decreeLayout/influence"
path
:
"/decreeLayout/influence"
//
},
},
]);
]);
const
activeTitle
=
ref
(
"政令概况"
);
const
activeTitle
=
ref
(
"政令概况"
);
...
@@ -377,9 +371,9 @@ onMounted(() => {
...
@@ -377,9 +371,9 @@ onMounted(() => {
flex-direction
:
column
;
flex-direction
:
column
;
.header-main
{
.header-main
{
width
:
100%
;
width
:
100%
;
b
ackground-color
:
#fff
;
b
order-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
)
;
box-shadow
:
0px
4px
10px
0px
rgba
(
0
,
0
,
0
,
0
.05
);
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
overflow
:
hidden
;
background
:
rgba
(
255
,
255
,
255
,
1
)
;
}
}
.layout-main-header
{
.layout-main-header
{
width
:
1600px
;
width
:
1600px
;
...
@@ -396,30 +390,32 @@ onMounted(() => {
...
@@ -396,30 +390,32 @@ onMounted(() => {
margin
:
0
auto
;
margin
:
0
auto
;
display
:
flex
;
display
:
flex
;
justify-content
:
space-between
;
justify-content
:
space-between
;
align-items
:
center
;
}
}
.layout-main-header-left-box
{
.layout-main-header-left-box
{
width
:
1100px
;
width
:
20px
;
margin-top
:
13px
;
flex
:
auto
;
margin-top
:
12px
;
.left-box-top
{
.left-box-top
{
height
:
64px
;
height
:
64px
;
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
.icon
{
.icon
{
width
:
64px
;
width
:
64px
;
height
:
64px
;
height
:
40px
;
border-radius
:
4px
;
overflow
:
hidden
;
overflow
:
hidden
;
img
{
img
{
width
:
100%
;
width
:
100%
;
height
:
100%
;
height
:
100%
;
object-fit
:
fill
;
}
}
}
}
.info
{
.info
{
width
:
700px
;
margin-left
:
10px
;
margin-left
:
9px
;
margin-right
:
40px
;
width
:
20px
;
flex
:
auto
;
.info-box1
{
.info-box1
{
width
:
700px
;
width
:
100%
;
color
:
rgba
(
59
,
65
,
75
,
1
);
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
font-size
:
20px
;
...
@@ -428,9 +424,6 @@ onMounted(() => {
...
@@ -428,9 +424,6 @@ onMounted(() => {
letter-spacing
:
0px
;
letter-spacing
:
0px
;
text-align
:
left
;
text-align
:
left
;
margin-top
:
5px
;
margin-top
:
5px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
.info-box2
{
.info-box2
{
margin-top
:
5px
;
margin-top
:
5px
;
...
@@ -444,15 +437,13 @@ onMounted(() => {
...
@@ -444,15 +437,13 @@ onMounted(() => {
letter-spacing
:
0px
;
letter-spacing
:
0px
;
text-align
:
left
;
text-align
:
left
;
display
:
flex
;
display
:
flex
;
margin-left
:
-10px
;
.info-box2-item
{
.info-box2-item
{
white-space
:
nowrap
;
padding
:
0
10px
;
padding
:
0
10px
;
}
}
.item3
{
.info-box2-item
:first-child
{
max-width
:
420px
;
padding-left
:
0px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
}
}
}
}
...
@@ -498,9 +489,9 @@ onMounted(() => {
...
@@ -498,9 +489,9 @@ onMounted(() => {
}
}
}
}
.layout-main-header-right-box
{
.layout-main-header-right-box
{
width
:
450px
;
margin-top
:
19px
;
.right-box-top
{
.right-box-top
{
white-space
:
nowrap
;
padding-top
:
11px
;
.time
{
.time
{
height
:
24px
;
height
:
24px
;
line-height
:
24px
;
line-height
:
24px
;
...
@@ -710,49 +701,5 @@ onMounted(() => {
...
@@ -710,49 +701,5 @@ onMounted(() => {
}
}
}
}
}
}
// .tool-box {
// position: fixed;
// z-index: 10000;
// bottom: 80px;
// left: 0;
// width: 48px;
// height: 144px;
// border-radius: 0px 10px 10px 0px;
// box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
// background: rgba(255, 255, 255, 1);
// .tool1 {
// width: 17px;
// height: 18px;
// margin-top: 17px;
// margin-left: 16px;
// cursor: pointer;
// img {
// width: 100%;
// height: 100%;
// }
// }
// .tool2 {
// width: 22px;
// height: 20px;
// margin-top: 26px;
// margin-left: 14px;
// cursor: pointer;
// img {
// width: 100%;
// height: 100%;
// }
// }
// .tool3 {
// width: 20px;
// height: 20px;
// margin-top: 25px;
// margin-left: 15px;
// cursor: pointer;
// img {
// width: 100%;
// height: 100%;
// }
// }
// }
}
}
</
style
>
</
style
>
\ No newline at end of file
src/views/decree/decreeLayout/influence/ChartRelation.vue
deleted
100644 → 0
浏览文件 @
3dea68fc
<
template
>
<div
class=
"relation-graph-wrapper"
>
<div
class=
"graph-controls"
>
<!-- 这项政令标志着中美AI竞争进入一个新阶段,其核心特征是 “精准封锁”与“体系输出”相结合。它短期内无疑会给中国AI产业链带来压力,但长期看,这场竞争更可能是一场围绕技术路线、生态系统和治理规则的持久战。 -->
<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>
</
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/images/echartsicon01.png'
import
echartsIcon02
from
'./assets/images/echartsicon02.png'
import
echartsIcon03
from
'./assets/images/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
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
width
=
containerRef
.
value
.
offsetWidth
||
800
const
height
=
containerRef
.
value
.
offsetHeight
||
600
switch
(
layoutType
)
{
case
1
:
initNormalGraph
(
layoutType
,
width
,
height
)
break
case
2
:
initTreeGraph
(
width
,
height
)
break
case
3
:
initCircularGraph
(
width
,
height
)
break
}
})
}
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
||
echartsIcon03
,
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
||
echartsIcon03
,
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
||
echartsIcon03
,
size
:
node
.
symbolSize
||
40
,
name
:
node
.
name
,
image
:
node
.
image
,
isSanctioned
:
node
.
isSanctioned
})
}
})
}
return
{
id
:
centerId
,
label
:
centerNode
.
name
||
''
,
img
:
centerNode
.
image
||
echartsIcon03
,
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
||
echartsIcon03
,
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
()
emit
(
'nodeClick'
,
model
)
})
graphInstance
.
value
.
on
(
'canvas:click'
,
()
=>
{
})
}
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
)
}
)
watch
(
()
=>
props
.
treeData
,
()
=>
{
if
(
currentLayoutType
.
value
===
2
)
{
initGraph
(
2
)
}
}
)
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
);
}
}
</
style
>
\ No newline at end of file
src/views/decree/decreeLayout/influence/com/AiTips.vue
0 → 100644
浏览文件 @
b16fe10d
<
template
>
<div
class=
"view-box"
>
<div
class=
"icon-left"
>
<img
src=
"../../assets/icons/ai.png"
alt=
""
>
</div>
<div
class=
"tips-content"
>
{{
props
.
tips
}}
</div>
<div
class=
"icon-right"
>
<img
src=
"../../assets/icons/right.png"
alt=
""
>
</div>
</div>
</
template
>
<
script
setup
lang=
"ts"
name=
"AiTips"
>
const
props
=
defineProps
({
tips
:
{
type
:
String
,
default
:
''
}
});
</
script
>
<
style
scoped
lang=
"scss"
>
.view-box
{
width
:
100%
;
display
:
flex
;
align-items
:
center
;
padding
:
7px
12px
;
border
:
1px
solid
rgba
(
231
,
243
,
255
,
1
);
border-radius
:
4px
;
background
:
rgba
(
246
,
250
,
255
,
1
);
.icon-left
{
width
:
20px
;
height
:
20px
;
img
{
width
:
100%
;
height
:
100%
;
object-fit
:
contain
;
}
}
.tips-content
{
color
:
rgb
(
5
,
95
,
194
);
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
margin-left
:
13px
;
flex
:
1
;
}
.icon-right
{
width
:
24px
;
height
:
24px
;
img
{
width
:
100%
;
height
:
100%
;
object-fit
:
contain
;
}
}
}
</
style
>
\ No newline at end of file
src/views/decree/decreeLayout/influence/ChartChain.vue
→
src/views/decree/decreeLayout/influence/
com/
ChartChain.vue
浏览文件 @
b16fe10d
<
template
>
<
template
>
<div
class=
"view-box"
>
<div
class=
"view-box"
>
<div
class=
"right-main"
>
<el-empty
v-if=
"!dataList?.length"
style=
"padding-top: 15%;"
description=
"暂无数据"
:image-size=
"100"
/>
<div
class=
"right-main-content"
>
<div
v-if=
"dataList.length"
class=
"main-content-main"
>
<div
class=
"hintWrap"
>
<div
class=
"main-mask"
<div
class=
"icon1"
></div>
@
wheel
.
prevent=
"handleWheel"
<div
class=
"title"
>
@
mousedown=
"handleMouseDown"
这项政令标志着中美AI竞争进入一个新阶段,其核心特征是 “精准封锁”与“体系输出”相结合。它短期内无疑会给中国AI产业链带来压力,但长期看,这场竞争更可能是一场围绕技术路线、生态系统和治理规则的持久战。
@
mouseup=
"handleMouseUp"
</div>
@
mouseleave=
"handleMouseUp"
<div
class=
"icon2Wrap"
>
@
mousemove=
"handleMouseMove"
<div
class=
"icon2"
></div>
></div>
</div>
<div
class=
"fishbone-container"
:style=
"
{ transform: `translate(${translateX}px, ${translateY}px) scale(${scale})`, transformOrigin: 'center center' }">
</div>
<div
class=
"right-main-content-main"
>
<div
class=
"fishbone-wrapper"
>
<div
class=
"fishbone-scroll-container"
ref=
"scrollContainerRef"
>
<div
class=
"fishbone"
v-if=
"dataList.length > 0"
>
<div
class=
"main-line"
:style=
"
{ width: dataList.length * 200 + 300 + 'px' }">
<!-- 主轴上的标签 -->
<!-- 主轴上的标签 -->
<div
class=
"main-line"
:style=
"
{ width: dataList.length * 200 + 300 + 'px' }">
<div
class=
"main-line-text"
v-for=
"(item, index) in dataList"
:key=
"'label-' + index"
<div
class=
"main-line-text"
v-for=
"(item, index) in dataList"
:key=
"'label-' + index"
:class=
"
{
:class=
"
{
'blue-theme': index
<
2
,
'blue-theme': index
<
2
,
...
@@ -27,36 +22,35 @@
...
@@ -27,36 +22,35 @@
</div>
</div>
</div>
</div>
<!-- 奇数索引的数据组放在上方 -->
<!-- 奇数索引的数据组放在上方 -->
<div
v-for=
"(causeGroup, groupIndex) in onFilterData(1)"
:key=
"'top-' +
groupIndex"
<div
v-for=
"(causeGroup, groupIndex) in onFilterData(1)"
:key=
"
groupIndex"
:class=
"getTopBoneClass(groupIndex)"
:style=
"
{ left: groupIndex * 400 + 42
0 + 'px' }">
class=
"top-bone"
:style=
"
{ left: groupIndex * 400 + 510 + 'px', height: (causeGroup.causes?.length) * 22 + 10
0 + 'px' }">
<div
class=
"left-bone"
>
<div
class=
"left-bone"
>
<div
class=
"left-bone-item"
v-for=
"(item, index) in getLeftItems(causeGroup.causes)"
:key=
"'left-' + index
"
>
<div
class=
"left-bone-item"
v-for=
"item in getLeftItems(causeGroup.causes)"
:key=
"item.id
"
>
<img
:src=
"defaultIcon2 || item.picture"
alt=
""
class=
"company-icon"
/>
<img
:src=
"defaultIcon2 || item.picture"
alt=
""
class=
"company-icon"
/>
<div
class=
"text"
:title=
"item.name"
>
{{
item
.
name
}}
</div>
<div
class=
"text"
:title=
"item.name"
>
{{
item
.
name
}}
</div>
<div
class=
"line"
></div>
<div
class=
"line"
></div>
</div>
</div>
</div>
</div>
<div
class=
"right-bone"
>
<div
class=
"right-bone"
>
<div
class=
"right-bone-item"
v-for=
"(item, index) in getRightItems(causeGroup.causes)"
:key=
"'right-' + index
"
>
<div
class=
"right-bone-item"
v-for=
"item in getRightItems(causeGroup.causes)"
:key=
"item.id
"
>
<div
class=
"line"
></div>
<div
class=
"line"
></div>
<img
:src=
"defaultIcon2 || item.picture"
alt=
""
class=
"company-icon"
/>
<img
:src=
"defaultIcon2 || item.picture"
alt=
""
class=
"company-icon"
/>
<div
class=
"text"
:title=
"item.name"
>
{{
item
.
name
}}
</div>
<div
class=
"text"
:title=
"item.name"
>
{{
item
.
name
}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 偶数索引的数据组放在下方 -->
<!-- 偶数索引的数据组放在下方 -->
<div
v-for=
"(causeGroup, groupIndex) in onFilterData(0)"
:key=
"'bottom-' +
groupIndex"
<div
v-for=
"(causeGroup, groupIndex) in onFilterData(0)"
:key=
"
groupIndex"
:class=
"getBottomBoneClass(groupIndex)"
:style=
"
{ left: groupIndex * 400 + 22
0 + 'px' }">
class=
"bottom-bone"
:style=
"
{ left: groupIndex * 400 + 310 + 'px', height: (causeGroup.causes?.length) * 22 + 10
0 + 'px' }">
<div
class=
"left-bone"
>
<div
class=
"left-bone"
>
<div
class=
"left-bone-item"
v-for=
"(item, index) in getLeftItems(causeGroup.causes)"
:key=
"'left-bottom-' + index
"
>
<div
class=
"left-bone-item"
v-for=
"item in getRightItems(causeGroup.causes)"
:key=
"item.id
"
>
<img
:src=
"defaultIcon2 || item.picture"
alt=
""
class=
"company-icon"
/>
<img
:src=
"defaultIcon2 || item.picture"
alt=
""
class=
"company-icon"
/>
<div
class=
"text"
:title=
"item.name"
>
{{
item
.
name
}}
</div>
<div
class=
"text"
:title=
"item.name"
>
{{
item
.
name
}}
</div>
<div
class=
"line"
></div>
<div
class=
"line"
></div>
</div>
</div>
</div>
</div>
<div
class=
"right-bone"
>
<div
class=
"right-bone"
>
<div
class=
"right-bone-item"
v-for=
"(item, index) in getRightItems(causeGroup.causes)"
:key=
"'right-bottom-' + index
"
>
<div
class=
"right-bone-item"
v-for=
"item in getLeftItems(causeGroup.causes)"
:key=
"item.id
"
>
<div
class=
"line"
></div>
<div
class=
"line"
></div>
<img
:src=
"defaultIcon2 || item.picture"
alt=
""
class=
"company-icon"
/>
<img
:src=
"defaultIcon2 || item.picture"
alt=
""
class=
"company-icon"
/>
<div
class=
"text"
:title=
"item.name"
>
{{
item
.
name
}}
</div>
<div
class=
"text"
:title=
"item.name"
>
{{
item
.
name
}}
</div>
...
@@ -64,14 +58,8 @@
...
@@ -64,14 +58,8 @@
</div>
</div>
</div>
</div>
</div>
</div>
<div
v-else
style=
"display: flex; justify-content: center; align-items: center; height: 200px; width: 100%"
>
<el-empty
description=
"暂无相关数据"
/>
</div>
</div>
</div>
</div>
<div
v-if=
"dataList.length"
class=
"main-content-footer"
>
</div>
<div
class=
"right-main-content-footer"
>
<div
class=
"footer-item footer-item1"
>
<div
class=
"footer-item footer-item1"
>
<div
class=
"footer-item-bottom"
>
<div
class=
"footer-item-bottom"
>
<div
class=
"icon"
>
<div
class=
"icon"
>
...
@@ -119,16 +107,49 @@
...
@@ -119,16 +107,49 @@
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/template
>
<
/template
>
<
script
setup
name
=
"ChartChain"
>
<
script
setup
name
=
"ChartChain"
>
import
{
ref
,
onMounted
}
from
"vue"
;
import
{
ref
,
onMounted
}
from
"vue"
;
import
defaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
defaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
noticeIcon
from
"./assets/images/notice-icon.png"
;
import
noticeIcon
from
".
.
/assets/images/notice-icon.png"
;
import
{
getDeepMiningSelect
,
getDeepMiningIndustry
,
getDeepMiningIndustryFishbone
,
getDeepMiningIndustryEntity
}
from
"@/api/exportControlV2.0"
;
import
{
getDeepMiningSelect
,
getDeepMiningIndustry
,
getDeepMiningIndustryFishbone
,
getDeepMiningIndustryEntity
}
from
"@/api/exportControlV2.0"
;
// 缩放功能处理
const
scale
=
ref
(
1
)
const
minScale
=
0.1
const
maxScale
=
10
const
handleWheel
=
(
e
)
=>
{
if
(
e
.
deltaY
<
0
)
{
// 放大:不超过最大值
scale
.
value
=
Math
.
min
(
scale
.
value
+
0.1
,
maxScale
)
}
else
{
// 缩小:不低于最小值
scale
.
value
=
Math
.
max
(
scale
.
value
-
0.1
,
minScale
)
}
}
// 移动功能处理
const
translateX
=
ref
(
0
)
// X轴位移
const
translateY
=
ref
(
0
)
// Y轴位移
let
isDragging
=
false
let
startX
=
0
let
startY
=
0
const
handleMouseMove
=
(
e
)
=>
{
if
(
!
isDragging
)
return
translateX
.
value
=
e
.
clientX
-
startX
translateY
.
value
=
e
.
clientY
-
startY
}
const
handleMouseDown
=
(
e
)
=>
{
// 排除右键/中键,只响应左键(e.button=0为左键)
if
(
e
.
button
!==
0
)
return
isDragging
=
true
startX
=
e
.
clientX
-
translateX
.
value
startY
=
e
.
clientY
-
translateY
.
value
}
const
handleMouseUp
=
()
=>
{
isDragging
=
false
}
// 实体清单-深度挖掘-产业链中国企业实体信息查询
// 实体清单-深度挖掘-产业链中国企业实体信息查询
const
cnEntityOnChainData
=
ref
({
}
);
const
cnEntityOnChainData
=
ref
({
}
);
const
getCnEntityOnChainData
=
async
()
=>
{
const
getCnEntityOnChainData
=
async
()
=>
{
...
@@ -173,16 +194,6 @@ const getRightItems = items => {
...
@@ -173,16 +194,6 @@ const getRightItems = items => {
const
midpoint
=
Math
.
ceil
(
items
.
length
/
2
);
const
midpoint
=
Math
.
ceil
(
items
.
length
/
2
);
return
items
.
slice
(
midpoint
);
return
items
.
slice
(
midpoint
);
}
;
}
;
// 获取上方鱼骨图位置类名
const
getTopBoneClass
=
index
=>
{
const
positions
=
[
"top-bone"
,
"top-bone1"
,
"top-bone2"
];
return
positions
[
index
%
3
]
||
"top-bone"
;
}
;
// 获取下方鱼骨图位置类名
const
getBottomBoneClass
=
index
=>
{
const
positions
=
[
"bottom-bone"
,
"bottom-bone1"
,
"bottom-bone2"
];
return
positions
[
index
%
3
]
||
"bottom-bone"
;
}
;
const
getFishboneData
=
async
()
=>
{
const
getFishboneData
=
async
()
=>
{
const
currentSanction
=
sanctionList
.
value
.
find
(
item
=>
item
.
id
===
currentSanctionId
.
value
);
const
currentSanction
=
sanctionList
.
value
.
find
(
item
=>
item
.
id
===
currentSanctionId
.
value
);
const
date
=
currentSanction
?
currentSanction
.
date
:
''
;
const
date
=
currentSanction
?
currentSanction
.
date
:
''
;
...
@@ -305,126 +316,35 @@ onMounted(() => {
...
@@ -305,126 +316,35 @@ onMounted(() => {
.
view
-
box
{
.
view
-
box
{
width
:
100
%
;
width
:
100
%
;
height
:
100
%
;
height
:
100
%
;
}
.
right
-
main
{
height
:
100
%
;
padding
:
11
px
16
px
20
px
;
.
right
-
main
-
content
{
height
:
100
%
;
display
:
flex
;
display
:
flex
;
flex
-
direction
:
column
;
flex
-
direction
:
column
;
.
hintWrap
{
.
main
-
content
-
main
{
display
:
flex
;
position
:
relative
;
align
-
items
:
center
;
padding
:
7
px
12
px
;
border
:
1
px
solid
rgba
(
231
,
243
,
255
,
1
);
border
-
radius
:
4
px
;
background
:
rgba
(
246
,
250
,
255
,
1
);
margin
-
bottom
:
9
px
;
.
icon1
{
width
:
19
px
;
height
:
20
px
;
height
:
20
px
;
background
-
image
:
url
(
"../assets/icons/ai.png"
);
flex
:
auto
;
background
-
size
:
100
%
100
%
;
flex
-
shrink
:
0
;
}
.
title
{
color
:
rgb
(
5
,
95
,
194
);
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
margin
-
left
:
13
px
;
flex
:
1
;
}
.
icon2Wrap
{
width
:
24
px
;
height
:
24
px
;
background
-
color
:
rgba
(
231
,
243
,
255
,
1
);
display
:
flex
;
display
:
flex
;
justify
-
content
:
center
;
align
-
items
:
center
;
align
-
items
:
center
;
border
-
radius
:
12
px
;
justify
-
content
:
center
;
margin
-
left
:
20
px
;
flex
-
shrink
:
0
;
.
icon2
{
width
:
24
px
;
height
:
24
px
;
background
-
image
:
url
(
"../assets/icons/right.png"
);
background
-
size
:
100
%
100
%
;
}
}
}
.
right
-
main
-
content
-
main
{
flex
:
1
;
position
:
relative
;
overflow
:
hidden
;
overflow
:
hidden
;
.
main
-
mask
{
.
fishbone
-
wrapper
{
position
:
absolute
;
position
:
relative
;
top
:
0
;
width
:
100
%
;
left
:
0
;
height
:
100
%
;
}
.
fishbone
-
scroll
-
container
{
display
:
flex
;
align
-
items
:
center
;
width
:
100
%
;
width
:
100
%
;
height
:
100
%
;
height
:
100
%
;
overflow
-
x
:
auto
;
z
-
index
:
3
;
overflow
-
y
:
auto
;
scrollbar
-
width
:
thin
;
scrollbar
-
color
:
rgba
(
144
,
202
,
249
,
0.5
)
transparent
;
&
::
-
webkit
-
scrollbar
{
height
:
6
px
;
}
}
&
::
-
webkit
-
scrollbar
-
track
{
.
fishbone
-
container
{
background
:
transparent
;
}
&
::
-
webkit
-
scrollbar
-
thumb
{
background
-
color
:
rgba
(
144
,
202
,
249
,
0.5
);
border
-
radius
:
3
px
;
}
}
.
fishbone
{
position
:
relative
;
position
:
relative
;
width
:
fit
-
content
;
height
:
100
%
;
margin
-
top
:
40
px
;
min
-
width
:
100
%
;
padding
-
left
:
275
px
;
margin
-
left
:
40
px
;
.
main
-
line
{
.
main
-
line
{
margin
-
top
:
280
px
;
width
:
1888
px
;
height
:
3
px
;
height
:
3
px
;
background
:
rgb
(
230
,
231
,
232
);
background
:
rgb
(
230
,
231
,
232
);
display
:
flex
;
display
:
flex
;
justify
-
content
:
space
-
between
;
justify
-
content
:
space
-
between
;
align
-
items
:
center
;
align
-
items
:
center
;
padding
:
0
100
px
;
// 虚线
&
::
after
{
content
:
''
;
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100
%
;
height
:
100
%
;
}
// 添加中间的文字块
// 添加中间的文字块
.
main
-
line
-
text
{
.
main
-
line
-
text
{
...
@@ -472,28 +392,28 @@ onMounted(() => {
...
@@ -472,28 +392,28 @@ onMounted(() => {
.
top
-
bone
{
.
top
-
bone
{
position
:
absolute
;
position
:
absolute
;
top
:
20
px
;
bottom
:
0
px
;
right
:
200
px
;
width
:
3
px
;
width
:
3
px
;
height
:
260
px
;
background
:
rgb
(
230
,
231
,
232
);
background
:
rgb
(
230
,
231
,
232
);
transform
-
origin
:
bottom
center
;
transform
:
skew
(
30
deg
);
transform
:
skew
(
30
deg
);
z
-
index
:
1
;
z
-
index
:
1
;
.
left
-
bone
{
.
left
-
bone
{
color
:
#
777
;
color
:
#
777
;
position
:
absolute
;
position
:
absolute
;
top
:
0
;
top
:
-
20
px
;
left
:
-
150
px
;
right
:
0
;
width
:
150
px
;
width
:
180
px
;
height
:
50
px
;
height
:
100
%
;
display
:
flex
;
flex
-
direction
:
column
;
justify
-
content
:
flex
-
end
;
// overflow: hidden;
.
left
-
bone
-
item
{
.
left
-
bone
-
item
{
transform
:
skew
(
-
30
deg
);
transform
:
skew
(
-
30
deg
);
height
:
45
px
;
height
:
40
px
;
margin
-
bottom
:
2
px
;
margin
:
4
px
0
;
margin
-
top
:
2
px
;
display
:
flex
;
display
:
flex
;
justify
-
content
:
flex
-
end
;
justify
-
content
:
flex
-
end
;
align
-
items
:
center
;
align
-
items
:
center
;
...
@@ -519,17 +439,18 @@ onMounted(() => {
...
@@ -519,17 +439,18 @@ onMounted(() => {
.
right
-
bone
{
.
right
-
bone
{
color
:
#
777
;
color
:
#
777
;
position
:
absolute
;
position
:
absolute
;
top
:
0
;
top
:
-
44
px
;
right
:
-
150
px
;
left
:
0
;
width
:
150
px
;
width
:
180
px
;
height
:
210
px
;
height
:
100
%
;
overflow
:
hidden
;
display
:
flex
;
flex
-
direction
:
column
;
justify
-
content
:
flex
-
end
;
.
right
-
bone
-
item
{
.
right
-
bone
-
item
{
transform
:
skew
(
-
30
deg
);
transform
:
skew
(
-
30
deg
);
height
:
39
px
;
height
:
40
px
;
margin
-
bottom
:
2
px
;
margin
:
4
px
0
;
margin
-
top
:
2
px
;
display
:
flex
;
display
:
flex
;
justify
-
content
:
flex
-
start
;
justify
-
content
:
flex
-
start
;
align
-
items
:
center
;
align
-
items
:
center
;
...
@@ -554,39 +475,30 @@ onMounted(() => {
...
@@ -554,39 +475,30 @@ onMounted(() => {
}
}
}
}
.
top
-
bone1
{
@
extend
.
top
-
bone
;
right
:
500
px
;
}
.
top
-
bone2
{
@
extend
.
top
-
bone
;
right
:
800
px
;
}
.
bottom
-
bone
{
.
bottom
-
bone
{
position
:
absolute
;
position
:
absolute
;
top
:
280
px
;
top
:
0
px
;
right
:
360
px
;
width
:
3
px
;
width
:
3
px
;
height
:
260
px
;
background
:
rgb
(
230
,
231
,
232
);
background
:
rgb
(
230
,
231
,
232
);
transform
-
origin
:
top
center
;
transform
:
skew
(
-
30
deg
);
transform
:
skew
(
-
30
deg
);
z
-
index
:
1
;
z
-
index
:
1
;
.
left
-
bone
{
.
left
-
bone
{
color
:
#
777
;
color
:
#
777
;
position
:
absolute
;
position
:
absolute
;
top
:
50
px
;
bottom
:
-
44
px
;
left
:
-
150
px
;
right
:
0
;
width
:
150
px
;
width
:
180
px
;
height
:
260
px
;
height
:
100
%
;
display
:
flex
;
flex
-
direction
:
column
;
justify
-
content
:
flex
-
start
;
.
left
-
bone
-
item
{
.
left
-
bone
-
item
{
transform
:
skew
(
30
deg
);
transform
:
skew
(
30
deg
);
height
:
39
px
;
height
:
40
px
;
margin
-
bottom
:
2
px
;
margin
:
4
px
0
;
margin
-
top
:
2
px
;
display
:
flex
;
display
:
flex
;
justify
-
content
:
flex
-
end
;
justify
-
content
:
flex
-
end
;
align
-
items
:
center
;
align
-
items
:
center
;
...
@@ -613,16 +525,18 @@ onMounted(() => {
...
@@ -613,16 +525,18 @@ onMounted(() => {
.
right
-
bone
{
.
right
-
bone
{
color
:
#
777
;
color
:
#
777
;
position
:
absolute
;
position
:
absolute
;
top
:
50
px
;
bottom
:
-
20
px
;
right
:
-
150
px
;
left
:
0
;
width
:
150
px
;
width
:
180
px
;
height
:
260
px
;
height
:
100
%
;
display
:
flex
;
flex
-
direction
:
column
;
justify
-
content
:
flex
-
start
;
.
right
-
bone
-
item
{
.
right
-
bone
-
item
{
transform
:
skew
(
30
deg
);
transform
:
skew
(
30
deg
);
height
:
35
px
;
height
:
40
px
;
margin
-
bottom
:
2
px
;
margin
:
4
px
0
;
margin
-
top
:
2
px
;
display
:
flex
;
display
:
flex
;
justify
-
content
:
flex
-
start
;
justify
-
content
:
flex
-
start
;
align
-
items
:
center
;
align
-
items
:
center
;
...
@@ -646,19 +560,9 @@ onMounted(() => {
...
@@ -646,19 +560,9 @@ onMounted(() => {
}
}
}
}
}
}
.
bottom
-
bone1
{
@
extend
.
bottom
-
bone
;
right
:
660
px
;
}
.
bottom
-
bone2
{
@
extend
.
bottom
-
bone
;
right
:
960
px
;
}
}
}
.
right
-
main
-
content
-
footer
{
.
main
-
content
-
footer
{
margin
-
top
:
16
px
;
margin
-
top
:
16
px
;
display
:
flex
;
display
:
flex
;
justify
-
content
:
space
-
between
;
justify
-
content
:
space
-
between
;
...
@@ -725,6 +629,5 @@ onMounted(() => {
...
@@ -725,6 +629,5 @@ onMounted(() => {
}
}
}
}
}
}
}
}
}
<
/style>
<
/style>
\ No newline at end of file
src/views/decree/decreeLayout/influence/index.vue
浏览文件 @
b16fe10d
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
</div>
</div>
<div
class=
"data-title"
>
实体名称
</div>
<div
class=
"data-title"
>
实体名称
</div>
<div
style=
"height: 20px; flex: auto;"
>
<div
style=
"height: 20px; flex: auto;"
>
<el-empty
v-if=
"
showCompanyList.length === 0"
style=
"padding-top: 30%
"
description=
"暂无数据"
:image-size=
"100"
/>
<el-empty
v-if=
"
!showCompanyList?.length"
style=
"padding-top: 35%;
"
description=
"暂无数据"
:image-size=
"100"
/>
<el-scrollbar
height=
"100%"
always
>
<el-scrollbar
height=
"100%"
always
>
<div
class=
"list-data"
>
<div
class=
"list-data"
>
<div
class=
"list-item"
v-for=
"item in showCompanyList"
:key=
"item.id"
:class=
"
{ 'item-active': activeEntityId === item.id }" @click="handleToCompanyDetail(item)">
<div
class=
"list-item"
v-for=
"item in showCompanyList"
:key=
"item.id"
:class=
"
{ 'item-active': activeEntityId === item.id }" @click="handleToCompanyDetail(item)">
...
@@ -75,19 +75,15 @@
...
@@ -75,19 +75,15 @@
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/template
>
<
/template
>
<
div
class
=
"box2-main"
v
-
if
=
"contentType==1"
>
<
div
class
=
"box2-main"
>
<
AiTips
:
tips
=
"tips"
/>
<
div
class
=
"graph-box"
v
-
if
=
"contentType==1"
>
<
ChartChain
/>
<
ChartChain
/>
<
/div
>
<
/div
>
<
div
class
=
"box2-main"
v
-
if
=
"contentType==2"
>
<
div
class
=
"graph-box"
v
-
if
=
"contentType==2"
>
<!--
<
ChartRelation
:
graph
-
data
=
"graphData"
:
tree
-
data
=
"treeData"
:
control
-
active
=
"1"
@
node
-
click
=
"handleNodeClick"
@
layout
-
change
=
"handleLayoutChange"
/>
-->
<
GraphChart
:
nodes
=
"testData.nodes"
:
links
=
"testData.links"
layoutType
=
"force"
/>
<
GraphChart
:
nodes
=
"testData.nodes"
:
links
=
"testData.links"
layoutType
=
"force"
/>
<
/div
>
<
/div
>
<
/div
>
<
/AnalysisBox
>
<
/AnalysisBox
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
...
@@ -101,9 +97,9 @@ import getBarChart from "./utils/barChart";
...
@@ -101,9 +97,9 @@ import getBarChart from "./utils/barChart";
import
{
getDecreeIndustry
,
getDecreehylyList
,
getDecreeCompany
}
from
"@/api/decree/influence"
;
import
{
getDecreeIndustry
,
getDecreehylyList
,
getDecreeCompany
}
from
"@/api/decree/influence"
;
import
{
getCnEntityOnChain
,
getChainInfoByDomainId
}
from
"@/api/exportControl"
;
import
{
getCnEntityOnChain
,
getChainInfoByDomainId
}
from
"@/api/exportControl"
;
import
{
getSingleSanctionEntitySupplyChain
}
from
"@/api/exportControlV2.0"
;
import
{
getSingleSanctionEntitySupplyChain
}
from
"@/api/exportControlV2.0"
;
import
ChartChain
from
"./ChartChain.vue"
;
import
ChartChain
from
"./com/ChartChain.vue"
;
import
AiTips
from
"./com/AiTips.vue"
;
import
GraphChart
from
"@/components/base/GraphChart/index.vue"
;
import
GraphChart
from
"@/components/base/GraphChart/index.vue"
;
import
ChartRelation
from
"./ChartRelation.vue"
;
import
defaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
defaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
noticeIcon
from
"./assets/images/notice-icon.png"
;
import
noticeIcon
from
"./assets/images/notice-icon.png"
;
import
icon422
from
"./assets/images/icon422.png"
;
import
icon422
from
"./assets/images/icon422.png"
;
...
@@ -113,191 +109,65 @@ import icon1621 from "./assets/images/icon1621.png";
...
@@ -113,191 +109,65 @@ import icon1621 from "./assets/images/icon1621.png";
import
company
from
"./assets/images/company.png"
;
import
company
from
"./assets/images/company.png"
;
import
companyActive
from
"./assets/images/company-active.png"
;
import
companyActive
from
"./assets/images/company-active.png"
;
const
tips
=
"这项政令标志着中美AI竞争进入一个新阶段,其核心特征是 “精准封锁”与“体系输出”相结合。它短期内无疑会给中国AI产业链带来压力,但长期看,这场竞争更可能是一场围绕技术路线、生态系统和治理规则的持久战。"
// 关系图数据
// 关系图数据
const
testData
=
{
const
testData
=
{
// 节点数据
// 节点数据
nodes
:
[
nodes
:
[
{
id
:
0
,
name
:
"泰丰先行"
,
symbolSize
:
60
,
symbol
:
`image://${company
}
`
,
x
:
0
,
y
:
0
}
,
{
id
:
1
,
name
:
"国轩高科"
,
symbolSize
:
40
,
symbol
:
`image://${company
}
`
}
,
{
id
:
2
,
name
:
"智方纳米"
,
symbolSize
:
40
,
symbol
:
`image://${company
}
`
}
,
{
id
:
3
,
name
:
"香百科技"
,
symbolSize
:
40
,
symbol
:
`image://${company
}
`
}
,
{
id
:
4
,
name
:
"格林滨"
,
symbolSize
:
40
,
symbol
:
`image://${company
}
`
}
,
{
id
:
5
,
name
:
"江西紫宸"
,
symbolSize
:
40
,
symbol
:
`image://${company
}
`
}
,
{
id
:
6
,
name
:
"紫江企业"
,
symbolSize
:
40
,
symbol
:
`image://${company
}
`
}
,
{
id
:
7
,
name
:
"大而美法案"
,
symbolSize
:
40
,
symbol
:
`image://${company
}
`
}
,
{
id
:
8
,
name
:
"比亚迪"
,
symbolSize
:
40
,
symbol
:
`image://${company
}
`
}
,
],
// 关系数据
links
:
[
{
{
id
:
0
,
source
:
1
,
target
:
0
,
name
:
"泰丰先行"
,
label
:
{
show
:
true
,
color
:
"#055FC2"
,
backgroundColor
:
"#E7F3FF"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
'持股'
}
,
// category: 0,
lineStyle
:
{
color
:
'#B9DCFF'
,
type
:
"solid"
}
symbolSize
:
30
,
value
:
8
,
symbol
:
`image://${company
}
`
,
x
:
50
,
y
:
10
}
,
{
id
:
1
,
name
:
"国轩高科"
,
// category: 0,
symbolSize
:
30
,
value
:
9
,
symbol
:
`image://${company
}
`
,
x
:
150
,
y
:
10
}
,
{
id
:
2
,
name
:
"智方纳米"
,
// category: 2,
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${company
}
`
,
x
:
250
,
y
:
10
}
,
{
id
:
3
,
name
:
"香百科技"
,
// category: 1,
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${company
}
`
,
x
:
350
,
y
:
10
}
,
{
id
:
4
,
name
:
"格林滨"
,
// category: 2,
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${company
}
`
,
x
:
450
,
y
:
10
}
,
{
id
:
5
,
name
:
"江西紫宸"
,
// category: 2,
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${company
}
`
,
x
:
550
,
y
:
10
}
,
{
id
:
6
,
name
:
"紫江企业"
,
// category: 4,
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${company
}
`
,
x
:
650
,
y
:
10
}
,
{
id
:
7
,
name
:
"大而美法案"
,
// category: 4,
symbolSize
:
50
,
value
:
5
,
symbol
:
`image://${company
}
`
,
x
:
300
,
y
:
200
}
,
{
id
:
8
,
name
:
"比亚迪"
,
// category: 0,
symbolSize
:
30
,
value
:
10
,
symbol
:
`image://${company
}
`
,
x
:
50
,
y
:
400
}
,
}
,
{
{
id
:
9
,
source
:
2
,
target
:
0
,
name
:
"铜陵有色"
,
label
:
{
show
:
true
,
color
:
"#055FC2"
,
backgroundColor
:
"#E7F3FF"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
'持股'
}
,
// category: 3,
lineStyle
:
{
color
:
'#B9DCFF'
,
type
:
"solid"
}
symbolSize
:
30
,
value
:
8
,
symbol
:
`image://${company
}
`
,
x
:
150
,
y
:
400
}
,
}
,
{
{
id
:
10
,
source
:
3
,
target
:
0
,
name
:
"长盛精密"
,
label
:
{
show
:
true
,
color
:
"#055FC2"
,
backgroundColor
:
"#E7F3FF"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
'合作'
}
,
// category: 1,
lineStyle
:
{
color
:
'#B9DCFF'
,
type
:
"solid"
}
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${company
}
`
,
x
:
250
,
y
:
400
}
,
}
,
{
{
id
:
11
,
source
:
4
,
target
:
0
,
name
:
"天合光能"
,
label
:
{
show
:
true
,
color
:
"#055FC2"
,
backgroundColor
:
"#E7F3FF"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
'从属'
}
,
// category: 0,
lineStyle
:
{
color
:
'#B9DCFF'
,
type
:
"solid"
}
symbolSize
:
30
,
value
:
8
,
symbol
:
`image://${company
}
`
,
x
:
350
,
y
:
400
}
,
}
,
{
{
id
:
12
,
source
:
5
,
target
:
0
,
name
:
"昆仑化学"
,
label
:
{
show
:
true
,
color
:
"#055FC2"
,
backgroundColor
:
"#E7F3FF"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
'合作'
}
,
// category: 2,
lineStyle
:
{
color
:
'#B9DCFF'
,
type
:
"solid"
}
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${company
}
`
,
x
:
250
,
y
:
400
}
,
}
,
{
{
id
:
13
,
source
:
6
,
target
:
0
,
name
:
"嘉源科技"
,
label
:
{
show
:
true
,
color
:
"#055FC2"
,
backgroundColor
:
"#E7F3FF"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
'持股'
}
,
// category: 1,
lineStyle
:
{
color
:
'#B9DCFF'
,
type
:
"solid"
}
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${company
}
`
,
x
:
450
,
y
:
400
}
,
}
,
{
{
id
:
14
,
source
:
7
,
target
:
0
,
name
:
"华阳集团"
,
label
:
{
show
:
true
,
color
:
"#055FC2"
,
backgroundColor
:
"#E7F3FF"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
'合作'
}
,
// category: 4,
lineStyle
:
{
color
:
'#B9DCFF'
,
type
:
"solid"
}
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${company
}
`
,
x
:
550
,
y
:
400
}
,
}
,
{
{
id
:
15
,
source
:
8
,
target
:
0
,
name
:
"海辰智能"
,
label
:
{
show
:
true
,
color
:
"#055FC2"
,
backgroundColor
:
"#E7F3FF"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
'合作'
}
,
// category: 1,
lineStyle
:
{
color
:
'#B9DCFF'
,
type
:
"solid"
}
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${company
}
`
,
x
:
650
,
y
:
400
}
,
}
,
],
],
// 关系数据
links
:
[
{
source
:
1
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
2
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'持股'
}
}
,
{
source
:
3
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
4
,
target
:
7
,
lineStyle
:
{
type
:
'dashed'
,
color
:
'#d32f2f'
}
,
label
:
{
show
:
true
,
formatter
:
'从属'
}
}
,
{
source
:
5
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
6
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'持股'
}
}
,
{
source
:
0
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'持股'
}
}
,
{
source
:
8
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
9
,
target
:
7
,
lineStyle
:
{
type
:
'dashed'
,
color
:
'#d32f2f'
}
,
label
:
{
show
:
true
,
formatter
:
'从属'
}
}
,
{
source
:
10
,
target
:
7
,
lineStyle
:
{
type
:
'dashed'
,
color
:
'#d32f2f'
}
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
11
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
12
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
13
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
14
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
15
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
,
color
:
'red'
,
borderColor
:
'red'
}
}
,
],
}
;
}
;
// 受影响实体
// 受影响实体
...
@@ -374,7 +244,7 @@ const handleGetHylyList = async () => {
...
@@ -374,7 +244,7 @@ const handleGetHylyList = async () => {
}
;
}
;
// 产业链/实体关系
// 产业链/实体关系
const
contentType
=
ref
(
2
);
const
contentType
=
ref
(
1
);
const
headerContentType
=
(
type
)
=>
{
const
headerContentType
=
(
type
)
=>
{
contentType
.
value
=
type
;
contentType
.
value
=
type
;
}
;
}
;
...
@@ -693,7 +563,7 @@ onMounted(() => {
...
@@ -693,7 +563,7 @@ onMounted(() => {
align
-
items
:
flex
-
end
;
align
-
items
:
flex
-
end
;
width
:
100
%
;
width
:
100
%
;
height
:
100
%
;
height
:
100
%
;
padding
:
0
16
px
;
padding
:
0
20
px
;
.
title
-
left
{
.
title
-
left
{
display
:
flex
;
display
:
flex
;
border
:
1
px
solid
rgb
(
5
,
95
,
194
);
border
:
1
px
solid
rgb
(
5
,
95
,
194
);
...
@@ -734,6 +604,14 @@ onMounted(() => {
...
@@ -734,6 +604,14 @@ onMounted(() => {
.
box2
-
main
{
.
box2
-
main
{
width
:
100
%
;
width
:
100
%
;
height
:
100
%
;
height
:
100
%
;
display
:
flex
;
flex
-
direction
:
column
;
padding
:
16
px
20
px
;
.
graph
-
box
{
height
:
20
px
;
flex
:
auto
;
margin
-
top
:
16
px
;
}
}
}
}
}
}
}
...
...
src/views/decree/decreeLayout/overview/background/index.vue
浏览文件 @
b16fe10d
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
<div
class=
"box1-main"
>
<div
class=
"box1-main"
>
<div
class=
"box1-item"
v-for=
"(item, index) in backgroundList"
:key=
"index"
>
<div
class=
"box1-item"
v-for=
"(item, index) in backgroundList"
:key=
"index"
>
<div
class=
"id"
>
{{ index + 1 }}
</div>
<div
class=
"id"
>
{{ index + 1 }}
</div>
<div
class=
"title"
>
{{ item.content }}
</div>
<div
class=
"title
text-align-justify
"
>
{{ item.content }}
</div>
<div
class=
"open"
>
<div
class=
"open"
>
<img
src=
"./assets/images/open-icon.png"
alt=
""
/>
<img
src=
"./assets/images/open-icon.png"
alt=
""
/>
</div>
</div>
...
@@ -37,14 +37,17 @@
...
@@ -37,14 +37,17 @@
<div
class=
"box2-main"
>
<div
class=
"box2-main"
>
<div
class=
"custom-collapse"
>
<div
class=
"custom-collapse"
>
<el-collapse
v-model=
"dependActive"
>
<el-collapse
v-model=
"dependActive"
>
<el-collapse-item
v-for=
"(item, index) in dependList"
:key=
"item.billId"
title=
"Consistency"
:name=
"item.billId"
>
<el-collapse-item
v-for=
"(item, index) in dependList"
:key=
"item.billId"
:name=
"item.billId"
>
<
template
#
icon
>
<
template
#
icon
>
<el-icon><ArrowDownBold
/></el-icon>
<el-icon
v-if=
"dependActive.includes(item.billId)"
><ArrowDownBold
/></el-icon>
<el-icon
v-else
><ArrowUpBold
/></el-icon>
</
template
>
</
template
>
<
template
#
title
>
<
template
#
title
>
<div
class=
"custom-collapse-title"
>
<div
class=
"custom-collapse-title"
>
<div
class=
"custom-collapse-index"
>
{{
index
+
1
}}
</div>
<div
class=
"custom-collapse-index"
>
{{
index
+
1
}}
</div>
<div
class=
"custom-collapse-name one-line-ellipsis"
>
{{
item
.
title
}}
</div>
<div
class=
"custom-collapse-name one-line-ellipsis"
>
<span
class=
"text-click-hover"
@
click
.
stop=
"handleClickDecree(item)"
>
{{
item
.
title
}}
</span>
</div>
</div>
</div>
</
template
>
</
template
>
<div
class=
"custom-collapse-content"
>
<div
class=
"custom-collapse-content"
>
...
@@ -192,6 +195,20 @@ const handleGetLaws = async () => {
...
@@ -192,6 +195,20 @@ const handleGetLaws = async () => {
console
.
error
(
"获取法律依据数据失败"
,
error
);
console
.
error
(
"获取法律依据数据失败"
,
error
);
}
}
};
};
// 跳转科技法案详情页
const
handleClickDecree
=
decree
=>
{
window
.
sessionStorage
.
setItem
(
"billId"
,
decree
.
billId
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
decree
.
title
);
const
route
=
router
.
resolve
({
path
:
"/billLayout"
,
query
:
{
billId
:
decree
.
billId
}
});
console
.
log
(
route
);
window
.
open
(
route
.
href
,
"_blank"
);
};
onMounted
(()
=>
{
onMounted
(()
=>
{
handleGetBackground
();
handleGetBackground
();
...
@@ -261,29 +278,31 @@ onMounted(() => {
...
@@ -261,29 +278,31 @@ onMounted(() => {
background
:
rgba
(
255
,
255
,
255
,
1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
padding
:
1
2
px
0
;
padding
:
1
8
px
0
;
.id
{
.id
{
margin-right
:
16px
;
margin-left
:
15px
;
margin-left
:
15px
;
width
:
24px
;
width
:
24px
;
height
:
24px
;
height
:
24px
;
text-align
:
center
;
text-align
:
center
;
line-height
:
30px
;
border-radius
:
12px
;
background
:
#e7f3ff
;
background
:
#e7f3ff
;
color
:
#0a57a6
;
color
:
#0a57a6
;
font-size
:
15px
;
line-height
:
24px
;
border-radius
:
50%
;
}
}
.title
{
.title
{
width
:
914
px
;
width
:
20
px
;
line-height
:
24px
;
flex
:
auto
;
margin-left
:
13
px
;
line-height
:
30
px
;
}
}
.open
{
.open
{
width
:
16px
;
width
:
16px
;
height
:
16px
;
height
:
16px
;
margin
-left
:
16px
;
margin
:
0
16px
;
img
{
img
{
width
:
100%
;
width
:
100%
;
...
@@ -332,7 +351,8 @@ onMounted(() => {
...
@@ -332,7 +351,8 @@ onMounted(() => {
.custom-collapse-title
{
.custom-collapse-title
{
position
:
relative
;
position
:
relative
;
.custom-collapse-index
{
.custom-collapse-index
{
font-size
:
15px
;
font-family
:
Microsoft
YaHei
;
font-size
:
var
(
--
font-size-base
);
position
:
absolute
;
position
:
absolute
;
top
:
12px
;
top
:
12px
;
left
:
-32px
;
left
:
-32px
;
...
...
src/views/decree/decreeLayout/overview/introduction/index.vue
浏览文件 @
b16fe10d
...
@@ -37,9 +37,6 @@
...
@@ -37,9 +37,6 @@
<div
class=
"item"
>
<div
class=
"item"
>
<div
class=
"item-left"
>
{{ "相关领域:" }}
</div>
<div
class=
"item-left"
>
{{ "相关领域:" }}
</div>
<div
class=
"item-right tag-box"
>
<div
class=
"item-right tag-box"
>
<!-- <div class="tag" v-for="(area, index) in basicInfo.areaList" :key="index">
{{ area.industryName }}
</div> -->
<AreaTag
v-for=
"(area, index) in basicInfo.areaList"
:key=
"index"
:tagName=
"area.industryName"
></AreaTag>
<AreaTag
v-for=
"(area, index) in basicInfo.areaList"
:key=
"index"
:tagName=
"area.industryName"
></AreaTag>
</div>
</div>
</div>
</div>
...
@@ -120,7 +117,7 @@
...
@@ -120,7 +117,7 @@
<img
:src=
"item.avatar ? item.avatar : DefaultIcon1"
alt=
""
/>
<img
:src=
"item.avatar ? item.avatar : DefaultIcon1"
alt=
""
/>
</div>
</div>
<div
class=
"box3-top-bottom-item-right"
>
<div
class=
"box3-top-bottom-item-right"
>
<div
class=
"name"
@
click=
"handleClickUser(item)"
>
{{ item.name }}
</div>
<div
class=
"name
text-click-hover one-line-ellipsis
"
@
click=
"handleClickUser(item)"
>
{{ item.name }}
</div>
<div
class=
"position"
>
{{ item.job }}
</div>
<div
class=
"position"
>
{{ item.job }}
</div>
</div>
</div>
</div>
</div>
...
@@ -336,22 +333,20 @@ onMounted(() => {
...
@@ -336,22 +333,20 @@ onMounted(() => {
.box1-main
{
.box1-main
{
display
:
flex
;
display
:
flex
;
padding
:
0
24px
;
.box1-main-left
{
.box1-main-left
{
width
:
395px
;
width
:
395px
;
height
:
332px
;
height
:
332px
;
margin-left
:
24px
;
img
{
img
{
width
:
100%
;
width
:
100%
;
// height: 100%;
}
}
}
}
.box1-main-left-img-mock
{
.box1-main-left-img-mock
{
width
:
240px
;
width
:
240px
;
height
:
332px
;
height
:
332px
;
margin-left
:
24px
;
background-color
:
#0b1932
;
background-color
:
#0b1932
;
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
...
@@ -378,7 +373,8 @@ onMounted(() => {
...
@@ -378,7 +373,8 @@ onMounted(() => {
}
}
.box1-main-right
{
.box1-main-right
{
width
:
590px
;
width
:
20px
;
flex
:
auto
;
margin-left
:
20px
;
margin-left
:
20px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-family
:
Microsoft
YaHei
;
...
@@ -387,24 +383,22 @@ onMounted(() => {
...
@@ -387,24 +383,22 @@ onMounted(() => {
line-height
:
24px
;
line-height
:
24px
;
.item
{
.item
{
height
:
30px
;
display
:
flex
;
display
:
flex
;
margin-bottom
:
17
px
;
margin-bottom
:
22
px
;
.item-left
{
.item-left
{
width
:
100px
;
width
:
100px
;
}
}
.item-right
{
.item-right
{
width
:
470px
;
width
:
20px
;
overflow
:
hidden
;
flex
:
auto
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
.tag-box
{
.tag-box
{
display
:
flex
;
display
:
flex
;
gap
:
8px
;
gap
:
8px
;
flex-wrap
:
wrap
;
.tag
{
.tag
{
height
:
24px
;
height
:
24px
;
...
@@ -423,6 +417,9 @@ onMounted(() => {
...
@@ -423,6 +417,9 @@ onMounted(() => {
}
}
.text
{
.text
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
font-weight
:
normal
!
important
;
font-weight
:
normal
!
important
;
}
}
}
}
...
@@ -697,10 +694,6 @@ onMounted(() => {
...
@@ -697,10 +694,6 @@ onMounted(() => {
line-height
:
24px
;
line-height
:
24px
;
letter-spacing
:
0px
;
letter-spacing
:
0px
;
text-align
:
left
;
text-align
:
left
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
cursor
:
pointer
;
}
}
.position
{
.position
{
...
...
src/views/decree/decreeLayout/overview/measures/index.vue
浏览文件 @
b16fe10d
<
template
>
<
template
>
<div
class=
"introduction-wrap"
>
<div
class=
"introduction-wrap"
>
<div
class=
"left"
>
<div
class=
"
page-
left"
>
<div
class=
"box1"
>
<div
class=
"box1"
>
<AnalysisBox
title=
"主要指令"
:showAllBtn=
"false"
>
<AnalysisBox
title=
"主要指令"
:showAllBtn=
"false"
>
<div
class=
"analysis-box"
>
<div
class=
"analysis-box"
>
...
@@ -21,7 +21,7 @@
...
@@ -21,7 +21,7 @@
<el-empty
v-if=
"!contentList?.length"
style=
"padding: 60px 0;"
description=
"暂无数据"
:image-size=
"100"
/>
<el-empty
v-if=
"!contentList?.length"
style=
"padding: 60px 0;"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-for=
"(section, index) in contentList"
:key=
"index"
class=
"section"
>
<div
v-for=
"(section, index) in contentList"
:key=
"index"
class=
"section"
>
<div
class=
"section-header"
>
<div
class=
"section-header"
>
<div
class=
"section-title
"
>
(
{{
simpleNumToChinese
(
index
+
1
)
}}
)
{{
section
.
content
}}
</div>
<div
class=
"section-title
text-align-justify"
v-html=
"section.content"
>
</div>
<div
class=
"section-icon"
>
<div
class=
"section-icon"
>
<img
src=
"./assets/images/open-icon.png"
alt=
""
/>
<img
src=
"./assets/images/open-icon.png"
alt=
""
/>
</div>
</div>
...
@@ -30,19 +30,19 @@
...
@@ -30,19 +30,19 @@
<div
class=
"numbered-list"
>
<div
class=
"numbered-list"
>
<div
v-for=
"(item, itemIndex) in section.slaver"
:key=
"itemIndex"
class=
"list-item"
>
<div
v-for=
"(item, itemIndex) in section.slaver"
:key=
"itemIndex"
class=
"list-item"
>
<div
class=
"list-item-dot"
>
{{
itemIndex
+
1
}}
.
</div>
<div
class=
"list-item-dot"
>
{{
itemIndex
+
1
}}
.
</div>
<div
class=
"list-item-word"
>
{{
item
.
content
}}
</div>
<div
class=
"list-item-word"
v-html=
"item.content"
>
</div>
<!-- 渲染二级列表 -->
<!-- 渲染二级列表 -->
<div
v-if=
"item.slaver"
class=
"sub-list"
>
<div
v-if=
"item.slaver"
class=
"sub-list"
>
<div
v-for=
"(subItem, subIndex) in item.slaver"
:key=
"subIndex"
class=
"sub-item"
>
<div
v-for=
"(subItem, subIndex) in item.slaver"
:key=
"subIndex"
class=
"sub-item"
>
<div
class=
"sub-item-dot"
>
(
{{
subIndex
+
1
}}
)
</div>
<div
class=
"sub-item-dot"
>
(
{{
subIndex
+
1
}}
)
</div>
<div
class=
"sub-item-word"
>
{{
subItem
.
content
}}
</div>
<div
class=
"sub-item-word"
v-html=
"subItem.content"
>
</div>
<!-- 渲染三级列表 -->
<!-- 渲染三级列表 -->
<div
v-if=
"subItem.slaver"
class=
"sub-sub-list"
>
<div
v-if=
"subItem.slaver"
class=
"sub-sub-list"
>
<div
v-for=
"(subSubItem, subSubIndex) in subItem.slaver"
:key=
"subSubIndex"
class=
"sub-sub-item"
>
<div
v-for=
"(subSubItem, subSubIndex) in subItem.slaver"
:key=
"subSubIndex"
class=
"sub-sub-item"
>
<div
class=
"sub-sub-item-dot"
>
{{
ALPHABET
[
subSubIndex
%
26
]
}}
.
</div>
<div
class=
"sub-sub-item-dot"
>
{{
ALPHABET
[
subSubIndex
%
26
]
}}
.
</div>
<div
class=
"sub-sub-item-word"
>
{{
subSubItem
.
content
}}
</div>
<div
class=
"sub-sub-item-word"
v-html=
"subItem.content"
>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -55,17 +55,22 @@
...
@@ -55,17 +55,22 @@
</AnalysisBox>
</AnalysisBox>
</div>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"
page-
right"
>
<div
class=
"box3"
>
<div
class=
"box3"
>
<AnalysisBox
title=
"
发布
机构"
:showAllBtn=
"false"
>
<AnalysisBox
title=
"
执行
机构"
:showAllBtn=
"false"
>
<div
class=
"box3-top"
>
<div
class=
"box3-top"
>
<div
class=
"box3-top-top"
@
click=
"handleToInstitution(box3TopTopData)"
>
<div
class=
"organization-list"
>
<div
class=
"organization-item"
v-for=
"item in organizationInfo.list"
:key=
"item.id"
>
<ActionButton
@
click=
"handleOrganization(item)"
:name=
"item.obb"
:type=
"item.id==organizationInfo.node.id?'active':'normal'"
/>
</div>
</div>
<div
class=
"box3-top-top"
@
click=
"handleToInstitution()"
>
<div
class=
"left"
>
<div
class=
"left"
>
<img
:src=
"
box3TopTopData.logo ? box3TopTopData.logo :
DefaultIcon2"
alt=
""
/>
<img
:src=
"
organizationInfo.node.logo ||
DefaultIcon2"
alt=
""
/>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right"
>
<div
class=
"name"
>
{{
box3TopTopData
.
name
+
" >"
}}
</div>
<div
class=
"name"
>
{{
organizationInfo
.
node
.
name
+
" >"
}}
</div>
<div
class=
"ename"
>
{{
box3TopTopData
.
eN
ame
}}
</div>
<div
class=
"ename"
>
{{
organizationInfo
.
node
.
en
ame
}}
</div>
</div>
</div>
</div>
</div>
<div
class=
"box3-top-bottom"
>
<div
class=
"box3-top-bottom"
>
...
@@ -76,17 +81,21 @@
...
@@ -76,17 +81,21 @@
<div
class=
"text"
>
{{
"关键人物"
}}
</div>
<div
class=
"text"
>
{{
"关键人物"
}}
</div>
</div>
</div>
<div
class=
"box3-top-bottom-main"
>
<div
class=
"box3-top-bottom-main"
>
<div
class=
"box3-top-bottom-item"
v-for=
"(item, index) in
box3TopBottomData
"
:key=
"index"
>
<div
class=
"box3-top-bottom-item"
v-for=
"(item, index) in
organizationInfo.node.leaders
"
:key=
"index"
>
<div
class=
"box3-top-bottom-item-left"
>
<div
class=
"box3-top-bottom-item-left"
>
<img
:src=
"item.avatar
? item.avatar :
DefaultIcon1"
alt=
""
/>
<img
:src=
"item.avatar
||
DefaultIcon1"
alt=
""
/>
</div>
</div>
<div
class=
"box3-top-bottom-item-right"
>
<div
class=
"box3-top-bottom-item-right"
>
<div
class=
"name"
@
click=
"handleClickUser(item)"
>
{{
item
.
name
}}
</div>
<div
class=
"name
one-line-ellipsis text-click-hover
"
@
click=
"handleClickUser(item)"
>
{{
item
.
name
}}
</div>
<div
class=
"position"
>
{{
item
.
job
}}
</div>
<div
class=
"position"
>
{{
item
.
job
}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"organization-button"
>
<div
class=
"button-text"
>
查看政令执行情况
</div>
<el-icon
size=
"16"
><Right
/></el-icon>
</div>
</div>
</div>
</AnalysisBox>
</AnalysisBox>
</div>
</div>
...
@@ -109,14 +118,14 @@
...
@@ -109,14 +118,14 @@
</
template
>
</
template
>
<
script
setup
>
<
script
setup
>
import
{
ref
,
onMounted
}
from
"vue"
;
import
{
ref
,
onMounted
,
reactive
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
useRoute
}
from
"vue-router"
;
import
router
from
"@/router"
;
import
router
from
"@/router"
;
import
{
Search
}
from
'@element-plus/icons-vue'
import
{
Search
}
from
'@element-plus/icons-vue'
import
{
getDecree
Issue
Organization
}
from
"@/api/decree/introduction"
;
import
{
getDecreeOrganization
}
from
"@/api/decree/introduction"
;
import
{
getDecreeRelatedEntity
,
getDecreeMainContent
}
from
"@/api/decree/background"
;
import
{
getDecreeRelatedEntity
,
getDecreeMainContent
}
from
"@/api/decree/background"
;
import
{
getDecreehylyList
}
from
"@/api/decree/home"
;
import
{
getDecreehylyList
}
from
"@/api/decree/home"
;
import
ActionButton
from
'@/components/base/ActionButton/index.vue'
import
DefaultIcon1
from
"@/assets/icons/default-icon1.png"
;
import
DefaultIcon1
from
"@/assets/icons/default-icon1.png"
;
import
DefaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
DefaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
defaultCom
from
"@/views/coopRestriction/assets/images/default-icon2.png"
import
defaultCom
from
"@/views/coopRestriction/assets/images/default-icon2.png"
...
@@ -211,14 +220,16 @@ const contentList = ref([
...
@@ -211,14 +220,16 @@ const contentList = ref([
const
ALPHABET
=
[
"a"
,
"b"
,
"c"
,
"d"
,
"e"
,
"f"
,
"g"
,
"h"
,
"i"
,
"j"
,
"k"
,
"l"
,
"m"
,
"n"
,
"o"
,
"p"
,
"q"
,
"r"
,
"s"
,
"t"
,
"u"
,
"v"
,
"w"
,
"x"
,
"y"
,
"z"
];
const
ALPHABET
=
[
"a"
,
"b"
,
"c"
,
"d"
,
"e"
,
"f"
,
"g"
,
"h"
,
"i"
,
"j"
,
"k"
,
"l"
,
"m"
,
"n"
,
"o"
,
"p"
,
"q"
,
"r"
,
"s"
,
"t"
,
"u"
,
"v"
,
"w"
,
"x"
,
"y"
,
"z"
];
const
onMainContentData
=
async
()
=>
{
const
onMainContentData
=
async
()
=>
{
try
{
try
{
const
res
=
await
getDecreeMainContent
({
const
keyword
=
commandWord
.
value
;
id
:
route
.
query
.
id
,
const
res
=
await
getDecreeMainContent
({
id
:
route
.
query
.
id
,
keyword
,
domainId
:
areaType
.
value
});
keyword
:
commandWord
.
value
,
domainId
:
areaType
.
value
});
console
.
log
(
"主要指令"
,
res
);
console
.
log
(
"主要指令"
,
res
);
if
(
res
&&
res
.
code
===
200
)
{
if
(
res
&&
res
.
code
===
200
)
{
contentList
.
value
=
res
.
data
;
contentList
.
value
=
res
.
data
||
[];
contentList
.
value
.
forEach
((
item
,
index
)
=>
{
item
.
content
=
`(
${
simpleNumToChinese
(
index
+
1
)}
)
${
item
.
content
}
`
})
if
(
keyword
)
{
let
word
=
keyword
.
replace
(
/
[
.*+?^${}()|[
\]\\]
/g
,
"
\\
$&"
);
contentList
.
value
.
forEach
(
item
=>
{
onHighlight
(
word
,
item
)})
}
}
else
{
}
else
{
contentList
.
value
=
[]
contentList
.
value
=
[]
}
}
...
@@ -227,12 +238,19 @@ const onMainContentData = async () => {
...
@@ -227,12 +238,19 @@ const onMainContentData = async () => {
console
.
error
(
"获取主要指令数据失败:"
,
error
);
console
.
error
(
"获取主要指令数据失败:"
,
error
);
}
}
};
};
// 搜索高亮效果
const
onHighlight
=
(
word
,
row
)
=>
{
row
.
content
=
String
(
row
.
content
).
replace
(
new
RegExp
(
word
,
"gi"
),
(
match
)
=>
{
return
`<span class="highlight">
${
match
}
</span>`
;
});
if
(
row
.
slaver
?.
length
)
{
row
.
slaver
.
forEach
(
item
=>
{
onHighlight
(
word
,
item
)
})
}
}
// 数字转中文(支持 0-99 整数)
// 数字转中文(支持 0-99 整数)
const
simpleNumToChinese
=
(
num
)
=>
{
const
simpleNumToChinese
=
(
num
)
=>
{
// 1. 基础校验:只处理 0-99 的整数
// 1. 基础校验:只处理 0-99 的整数
if
(
!
Number
.
isInteger
(
num
)
||
num
<
0
||
num
>
99
)
{
if
(
!
Number
.
isInteger
(
num
)
||
num
<
0
||
num
>
99
)
return
'100'
;
return
'仅支持 0-99 之间的整数'
;
}
// 2. 定义基础字符
// 2. 定义基础字符
const
singleChars
=
[
'零'
,
'一'
,
'二'
,
'三'
,
'四'
,
'五'
,
'六'
,
'七'
,
'八'
,
'九'
];
const
singleChars
=
[
'零'
,
'一'
,
'二'
,
'三'
,
'四'
,
'五'
,
'六'
,
'七'
,
'八'
,
'九'
];
const
tenChar
=
'十'
;
const
tenChar
=
'十'
;
...
@@ -271,20 +289,34 @@ const onRelatedEntityData = async () => {
...
@@ -271,20 +289,34 @@ const onRelatedEntityData = async () => {
}
}
};
};
// 发布机构
// 执行机构
const
box3TopTopData
=
ref
({
const
organizationInfo
=
reactive
({
id
:
""
,
list
:
[],
logo
:
""
,
node
:
{
id
:
""
,
obb
:
""
,
logo
:
""
,
name
:
""
,
ename
:
""
,
leaders
:
[]},
name
:
""
,
})
eName
:
""
const
handleGetOrgnization
=
async
()
=>
{
});
try
{
const
box3TopBottomData
=
ref
([]);
const
res
=
await
getDecreeOrganization
({
id
:
route
.
query
.
id
});
// 跳转行政机构主页
console
.
log
(
"执行机构"
,
res
);
const
handleToInstitution
=
item
=>
{
if
(
res
.
code
===
200
&&
res
.
data
?.
length
)
{
organizationInfo
.
list
=
res
.
data
;
organizationInfo
.
node
=
res
.
data
[
0
];
}
}
catch
(
error
)
{
organizationInfo
.
node
=
{
id
:
""
,
obb
:
""
,
logo
:
""
,
name
:
""
,
ename
:
""
,
leaders
:
[]};
console
.
error
(
"获取执行机构数据失败"
,
error
);
}
};
// 切换执行机构
const
handleOrganization
=
(
node
)
=>
{
organizationInfo
.
node
=
node
;
};
// 跳转机构主页
const
handleToInstitution
=
()
=>
{
const
curRoute
=
router
.
resolve
({
const
curRoute
=
router
.
resolve
({
path
:
"/institution"
,
path
:
"/institution"
,
query
:
{
query
:
{
id
:
item
.
id
id
:
organizationInfo
.
node
.
id
}
}
});
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
window
.
open
(
curRoute
.
href
,
"_blank"
);
...
@@ -300,21 +332,6 @@ const handleClickUser = item => {
...
@@ -300,21 +332,6 @@ const handleClickUser = item => {
});
});
window
.
open
(
routeData
.
href
,
"_blank"
);
window
.
open
(
routeData
.
href
,
"_blank"
);
};
};
const
handleGetOrgnization
=
async
()
=>
{
try
{
const
res
=
await
getDecreeIssueOrganization
({
id
:
route
.
query
.
id
});
console
.
log
(
"发布机构"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
let
{
id
,
image
,
name
,
ename
}
=
res
.
data
Object
.
assign
(
box3TopTopData
.
value
,
{
id
,
logo
:
image
,
name
,
eName
:
ename
});
box3TopBottomData
.
value
=
res
.
data
.
personList
;
}
}
catch
(
error
)
{
box3TopTopData
.
value
=
{
id
:
""
,
logo
:
""
,
name
:
""
,
eName
:
""
};
box3TopBottomData
.
value
=
[];
console
.
error
(
"执行机构error"
,
error
);
}
};
onMounted
(()
=>
{
onMounted
(()
=>
{
handleGetAreaList
();
handleGetAreaList
();
...
@@ -325,13 +342,19 @@ onMounted(() => {
...
@@ -325,13 +342,19 @@ onMounted(() => {
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.analysis-content
{
:deep
(
span
.highlight
)
{
background-color
:
#ffff00
;
}
}
.introduction-wrap
{
.introduction-wrap
{
display
:
flex
;
display
:
flex
;
width
:
1600px
;
width
:
1600px
;
padding
:
16px
0
;
padding
:
16px
0
;
gap
:
16px
;
gap
:
16px
;
.left
{
.
page-
left
{
width
:
20px
;
width
:
20px
;
flex
:
auto
;
flex
:
auto
;
...
@@ -387,7 +410,6 @@ onMounted(() => {
...
@@ -387,7 +410,6 @@ onMounted(() => {
.section-title
{
.section-title
{
font-size
:
18px
;
font-size
:
18px
;
line-height
:
30px
;
line-height
:
30px
;
font-weight
:
600
;
letter-spacing
:
1px
;
letter-spacing
:
1px
;
width
:
20px
;
width
:
20px
;
flex
:
auto
;
flex
:
auto
;
...
@@ -457,7 +479,7 @@ onMounted(() => {
...
@@ -457,7 +479,7 @@ onMounted(() => {
}
}
}
}
.right
{
.
page-
right
{
width
:
520px
;
width
:
520px
;
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
...
@@ -466,10 +488,34 @@ onMounted(() => {
...
@@ -466,10 +488,34 @@ onMounted(() => {
.box3
{
.box3
{
.box3-top
{
.box3-top
{
margin-top
:
2px
;
margin-top
:
2px
;
padding
:
0
22px
20px
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
.organization-list
{
display
:
flex
;
flex-wrap
:
wrap
;
margin-bottom
:
16px
;
gap
:
8px
16px
;
}
.organization-button
{
height
:
36px
;
background-color
:
var
(
--
color-primary-100
);
color
:
var
(
--
bg-white-100
);
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
border-radius
:
6px
;
cursor
:
pointer
;
.button-text
{
margin-right
:
8px
;
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
line-height
:
16px
;
}
}
.box3-top-top
{
.box3-top-top
{
width
:
473px
;
height
:
88px
;
height
:
88px
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
...
@@ -477,42 +523,13 @@ onMounted(() => {
...
@@ -477,42 +523,13 @@ onMounted(() => {
background
:
rgba
(
247
,
248
,
249
,
1
);
background
:
rgba
(
247
,
248
,
249
,
1
);
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
margin
:
0
auto
;
position
:
relative
;
cursor
:
pointer
;
cursor
:
pointer
;
.more
{
position
:
absolute
;
right
:
17px
;
top
:
17px
;
display
:
flex
;
gap
:
3px
;
.text
{
height
:
16px
;
color
:
rgba
(
5
,
95
,
194
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
16px
;
}
.icon
{
width
:
16px
;
height
:
16px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
}
.left
{
.left
{
width
:
64px
;
width
:
64px
;
height
:
64px
;
height
:
64px
;
margin-left
:
17px
;
margin-left
:
17px
;
font-size
:
0px
;
img
{
img
{
width
:
100%
;
width
:
100%
;
height
:
100%
;
height
:
100%
;
...
@@ -520,7 +537,8 @@ onMounted(() => {
...
@@ -520,7 +537,8 @@ onMounted(() => {
}
}
.right
{
.right
{
width
:
370px
;
width
:
20px
;
flex
:
auto
;
margin-left
:
15px
;
margin-left
:
15px
;
.name
{
.name
{
...
@@ -545,9 +563,7 @@ onMounted(() => {
...
@@ -545,9 +563,7 @@ onMounted(() => {
}
}
.box3-top-bottom
{
.box3-top-bottom
{
width
:
473px
;
height
:
193px
;
height
:
193px
;
margin
:
0
auto
;
.box3-top-bottom-header
{
.box3-top-bottom-header
{
height
:
40px
;
height
:
40px
;
...
@@ -624,10 +640,6 @@ onMounted(() => {
...
@@ -624,10 +640,6 @@ onMounted(() => {
line-height
:
24px
;
line-height
:
24px
;
letter-spacing
:
0px
;
letter-spacing
:
0px
;
text-align
:
left
;
text-align
:
left
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
cursor
:
pointer
;
}
}
.position
{
.position
{
...
...
src/views/decree/decreeOriginal/assets/icons/download.png
deleted
100644 → 0
浏览文件 @
3dea68fc
350 Bytes
src/views/decree/decreeOriginal/assets/icons/search.png
deleted
100644 → 0
浏览文件 @
3dea68fc
399 Bytes
src/views/decree/decreeOriginal/index.vue
浏览文件 @
b16fe10d
...
@@ -135,7 +135,6 @@ onMounted(() => {
...
@@ -135,7 +135,6 @@ onMounted(() => {
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
align-items
:
center
;
align-items
:
center
;
.header-main
{
.header-main
{
padding
:
17px
0
;
padding
:
17px
0
;
width
:
100%
;
width
:
100%
;
...
...
vite.config.js
浏览文件 @
b16fe10d
...
@@ -53,7 +53,7 @@ export default defineConfig({
...
@@ -53,7 +53,7 @@ export default defineConfig({
'/api'
:
{
'/api'
:
{
target
:
'http://8.140.26.4:9085/'
,
target
:
'http://8.140.26.4:9085/'
,
// target: 'http://192.168.0.
5
:28080/',
// target: 'http://192.168.0.
6
:28080/',
changeOrigin
:
true
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api/
,
''
)
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api/
,
''
)
},
},
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论