Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
cfd54036
提交
cfd54036
authored
3月 21, 2026
作者:
张烨
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat:政令增加实体关系图
上级
250ad91d
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
143 行增加
和
63 行删除
+143
-63
index.html
index.html
+2
-1
config.js
public/js/config.js
+2
-2
home.js
src/api/decree/home.js
+32
-10
influence.js
src/api/decree/influence.js
+8
-0
introduction.js
src/api/decree/introduction.js
+9
-0
index.vue
src/views/decree/decreeHome/index.vue
+0
-0
ChartChain.vue
src/views/decree/decreeLayout/influence/com/ChartChain.vue
+0
-0
index.vue
src/views/decree/decreeLayout/influence/index.vue
+61
-32
index.vue
...views/decree/decreeLayout/overview/introduction/index.vue
+24
-13
index.vue
src/views/decree/decreeOriginal/index.vue
+4
-2
vite.config.js
vite.config.js
+1
-3
没有找到文件。
index.html
浏览文件 @
cfd54036
...
...
@@ -9,6 +9,6 @@
<body>
<div
id=
"app"
></div>
<script
type=
"module"
src=
"/src/main.js"
></script>
<script
src=
"./config.js"
></script>
<script
src=
"./
js/
config.js"
></script>
</body>
</html>
\ No newline at end of file
public/js/config.js
浏览文件 @
cfd54036
const
baseUrl
=
`http://8.140.26.4:9085/`
\ No newline at end of file
const
baseUrl
=
`http://8.140.26.4:9085`
\ No newline at end of file
src/api/decree/home.js
浏览文件 @
cfd54036
...
...
@@ -5,6 +5,7 @@ export function getDepartmentList(params) {
return
request
({
method
:
'GET'
,
url
:
`/api/administrativeDict/department`
,
params
})
}
...
...
@@ -27,34 +28,36 @@ export function getDecreeRiskSignal(params) {
// 行政令发布频度
export
function
getDecreeYearOrder
(
params
)
{
return
request
({
method
:
'
GE
T'
,
url
:
`/api/administrativeOrderOverview/yearOrder
/
${
params
.
year
}
`
,
params
method
:
'
POS
T'
,
url
:
`/api/administrativeOrderOverview/yearOrder`
,
data
:
params
})
}
// 政令涉及领域
export
function
getDecreeArea
(
params
)
{
return
request
({
method
:
'
GE
T'
,
url
:
`/api/administrativeOrderOverview/industry
/
${
params
.
year
}
`
,
params
method
:
'
POS
T'
,
url
:
`/api/administrativeOrderOverview/industry`
,
data
:
params
})
}
// 关键行政令
export
function
getKeyDecree
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/administrativeOrderOverview/action?pageSize=
${
params
.
pageSize
}
&pageNum=
${
params
.
pageNum
}
`
,
method
:
'POST'
,
url
:
`/api/administrativeOrderOverview/action`
,
data
:
params
})
}
// 政令重点条款
export
function
getDecreeKeyInstruction
()
{
export
function
getDecreeKeyInstruction
(
params
)
{
return
request
({
method
:
'
GE
T'
,
method
:
'
POS
T'
,
url
:
`/api/administrativeOrderOverview/instruction`
,
data
:
params
})
}
...
...
@@ -85,4 +88,22 @@ export function getDecreeTypeList() {
method
:
'GET'
,
url
:
`/api/administrativeDict/type`
,
})
}
// 关键机构
export
function
getKeyOrganization
()
{
return
request
({
method
:
'GET'
,
url
:
`/api/commonFeature/keyOrganization`
,
})
}
// AI智能总结
export
function
getChartInterpretation
(
params
)
{
return
request
({
method
:
'POST'
,
url
:
`/aiAnalysis/chart_interpretation`
,
headers
:
{
"X-API-Key"
:
"aircasKEY19491001"
},
data
:
params
})
}
\ No newline at end of file
src/api/decree/influence.js
浏览文件 @
cfd54036
...
...
@@ -45,6 +45,14 @@ export function getDecreeChainNodes(params) {
})
}
// 获取实体关系节点列表
export
function
getDecreeRelatedEntitie
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/administrativeOrderInfo/listRelatedEntitie/
${
params
.
id
}
`
,
})
}
// 根据政行业领域ID获取公司列表
/**
* @param {cRelated, id}
...
...
src/api/decree/introduction.js
浏览文件 @
cfd54036
...
...
@@ -77,4 +77,12 @@ export function getDecreeReport(params) {
method
:
'GET'
,
url
:
`/api/administrativeOrderInfo/contentUrl/
${
params
.
id
}
`
,
})
}
// 政令关键词云
export
function
getKeyWordUp
()
{
return
request
({
method
:
'GET'
,
url
:
`/api/element//getKeyWordUp/2025-01-01`
,
})
}
\ No newline at end of file
src/views/decree/decreeHome/index.vue
浏览文件 @
cfd54036
差异被折叠。
点击展开。
src/views/decree/decreeLayout/influence/com/ChartChain.vue
浏览文件 @
cfd54036
差异被折叠。
点击展开。
src/views/decree/decreeLayout/influence/index.vue
浏览文件 @
cfd54036
...
...
@@ -19,7 +19,7 @@
<el-empty
v-if=
"!entityInfo.list?.length"
style=
"padding: 60px 0;"
description=
"暂无数据"
:image-size=
"100"
/>
<el-scrollbar
height=
"100%"
always
>
<div
class=
"list-data"
>
<div
class=
"list-item"
v-for=
"item in entityInfo.list"
:key=
"item.id"
:class=
"
{ 'item-active': entityInfo.id==item.id }" @click="
onDecreeRelatedChain
(item)">
<div
class=
"list-item"
v-for=
"item in entityInfo.list"
:key=
"item.id"
:class=
"
{ 'item-active': entityInfo.id==item.id }" @click="
headerChartData
(item)">
<div
class=
"item-icon"
>
<img
:src=
"defaultIcon2"
alt=
""
class=
"item-img"
/>
</div>
...
...
@@ -79,7 +79,7 @@
<
div
class
=
"graph-box"
v
-
if
=
"contentType==1"
>
<
ChartChain
:
listData
=
"fishbone.list"
:
baseData
=
"fishbone.base"
/>
<
/div
>
<
div
class
=
"graph-box"
v
-
if
=
"contentType==2"
>
<
div
class
=
"graph-box"
v
-
if
=
"contentType==2
&& graphInfo.nodes.length
"
>
<
GraphChart
:
nodes
=
"graphInfo.nodes"
:
links
=
"graphInfo.links"
layoutType
=
"force"
/>
<
/div
>
<
/div
>
...
...
@@ -92,7 +92,13 @@
import
{
ref
,
onMounted
,
reactive
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
Search
}
from
'@element-plus/icons-vue'
import
{
getDecreehylyList
,
getDecreeEntities
,
getDecreeRelatedChain
,
getDecreeChainNodes
}
from
"@/api/decree/influence"
;
import
{
getDecreehylyList
,
getDecreeEntities
,
getDecreeRelatedChain
,
getDecreeChainNodes
,
getDecreeRelatedEntitie
}
from
"@/api/decree/influence"
;
import
ChartChain
from
"./com/ChartChain.vue"
;
import
AiTips
from
"./com/AiTips.vue"
;
import
GraphChart
from
"@/components/base/GraphChart/index.vue"
;
...
...
@@ -133,18 +139,25 @@ const entityInfo = reactive({
total
:
0
,
list
:
[],
id
:
''
,
node
:
{
id
:
''
,
companyName
:
''
}
,
}
)
const
onDecreeEntities
=
async
(
page
=
1
)
=>
{
entityInfo
.
pageNum
=
page
;
try
{
let
{
pageSize
,
pageNum
,
keyword
}
=
entityInfo
;
const
res
=
await
getDecreeEntities
({
id
:
route
.
query
.
id
,
pageSize
,
pageNum
:
pageNum
-
1
,
keyword
}
);
let
params
=
{
id
:
route
.
query
.
id
,
pageSize
:
entityInfo
.
pageSize
,
pageNum
:
entityInfo
.
pageNum
-
1
,
keyword
:
entityInfo
.
keyword
,
domainId
:
areaInfo
.
id
||
undefined
}
const
res
=
await
getDecreeEntities
(
params
);
console
.
log
(
"受影响实体:"
,
res
);
if
(
res
.
code
===
200
)
{
entityInfo
.
list
=
res
.
data
.
companyInfos
;
entityInfo
.
total
=
res
.
data
.
total
;
if
(
entityInfo
.
total
&&
entityInfo
.
list
.
every
(
item
=>
item
.
id
!=
entityInfo
.
id
))
{
onDecreeRelatedChain
(
entityInfo
.
list
[
0
])
headerChartData
(
entityInfo
.
list
[
0
])
}
}
}
catch
(
error
)
{
...
...
@@ -155,20 +168,39 @@ const onDecreeEntities = async (page=1) => {
const
contentType
=
ref
(
1
);
const
headerContentType
=
(
type
)
=>
{
contentType
.
value
=
type
;
headerChartData
(
entityInfo
.
node
)
}
;
const
headerChartData
=
(
row
)
=>
{
entityInfo
.
id
=
row
.
id
;
entityInfo
.
node
=
row
;
industryChain
.
id
=
""
;
fishbone
.
list
=
[]
fishbone
.
base
=
[]
graphInfo
.
nodes
=
[];
graphInfo
.
links
=
[];
switch
(
contentType
.
value
)
{
case
1
:
onDecreeRelatedChain
(
row
.
id
)
break
;
case
2
:
onDecreeRelatedEntitie
(
row
.
id
)
break
;
}
}
// 产业链
const
industryChain
=
reactive
({
list
:
[],
id
:
""
,
}
)
const
onDecreeRelatedChain
=
async
({
id
}
)
=>
{
entityInfo
.
id
=
id
;
const
onDecreeRelatedChain
=
async
(
id
)
=>
{
try
{
const
res
=
await
getDecreeRelatedChain
({
id
}
);
console
.
log
(
"产业链:"
,
res
);
if
(
res
.
code
===
200
)
{
industryChain
.
id
=
""
;
industryChain
.
list
=
res
.
data
;
if
(
industryChain
.
list
.
length
)
onDecreeChainNodes
(
industryChain
.
list
[
0
].
id
)
}
...
...
@@ -184,8 +216,6 @@ const fishbone = reactive({
}
)
const
onDecreeChainNodes
=
async
(
id
)
=>
{
industryChain
.
id
=
id
;
fishbone
.
list
=
[]
fishbone
.
base
=
[]
try
{
const
res
=
await
getDecreeChainNodes
({
id
}
);
console
.
log
(
"产业链鱼骨图:"
,
res
);
...
...
@@ -195,11 +225,14 @@ const onDecreeChainNodes = async (id) => {
return
result
;
}
,
{
}
);
res
.
data
.
children
.
forEach
(
item
=>
{
if
(
obj
[
'chain-'
+
item
.
chainId
]?.
children
?.
length
<
10
)
{
if
(
item
.
companyId
==
entityInfo
.
id
)
{
obj
[
'chain-'
+
item
.
chainId
].
children
.
push
({
...
item
,
back
:
true
}
)
}
else
if
(
obj
[
'chain-'
+
item
.
chainId
]?.
children
?.
length
<
10
)
{
obj
[
'chain-'
+
item
.
chainId
].
children
.
push
(
item
)
}
}
)
fishbone
.
list
=
Object
.
values
(
obj
);
console
.
log
(
"fishbone.list:"
,
fishbone
.
list
);
fishbone
.
base
=
res
.
data
.
levelInfos
.
map
((
item
,
index
)
=>
{
return
{...
item
,
name
:
[
'上游'
,
'中游'
,
'下游'
][
index
]
}
}
);
...
...
@@ -211,38 +244,35 @@ const onDecreeChainNodes = async (id) => {
// 实体关系
const
graphInfo
=
reactive
({
leader
:
{
id
:
0
,
name
:
"泰丰先行"
}
,
list
:
[
{
id
:
1
,
name
:
"国轩高科"
,
formatter
:
'持股'
}
,
{
id
:
2
,
name
:
"智方纳米"
,
formatter
:
'持股'
}
,
{
id
:
3
,
name
:
"香百科技"
,
formatter
:
'合作'
}
,
{
id
:
4
,
name
:
"格林滨"
,
formatter
:
'从属'
}
,
{
id
:
5
,
name
:
"江西紫宸"
,
formatter
:
'合作'
}
,
{
id
:
6
,
name
:
"紫江企业"
,
formatter
:
'持股'
}
,
{
id
:
7
,
name
:
"大而美法案"
,
formatter
:
'合作'
}
,
{
id
:
8
,
name
:
"比亚迪"
,
formatter
:
'合作'
}
,
],
nodes
:
[],
links
:
[],
}
);
const
initGraphChart
=
()
=>
{
graphInfo
.
links
=
graphInfo
.
list
.
map
(
onFormatLink
)
graphInfo
.
nodes
=
graphInfo
.
list
.
map
(
onFormatNode
)
graphInfo
.
nodes
.
unshift
(
onFormatNode
(
graphInfo
.
leader
))
const
onDecreeRelatedEntitie
=
async
(
id
)
=>
{
try
{
const
res
=
await
getDecreeRelatedEntitie
({
id
}
);
console
.
log
(
"实体关系:"
,
res
);
if
(
res
.
code
===
200
)
{
graphInfo
.
links
=
res
.
data
.
map
(
onFormatLink
)
graphInfo
.
nodes
=
res
.
data
.
map
(
onFormatNode
)
graphInfo
.
nodes
.
unshift
(
onFormatNode
(
entityInfo
.
node
))
}
}
catch
(
error
)
{
console
.
log
(
"获取实体关系失败"
,
error
);
}
}
const
onFormatLink
=
(
item
,
index
)
=>
{
return
{
id
:
`link-${index+1
}
`
,
source
:
item
.
id
+
''
,
target
:
'0
'
,
label
:
{
show
:
true
,
color
:
"#055fc2"
,
backgroundColor
:
"#eef7ff"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
item
.
formatter
}
,
source
:
item
.
id
+
''
,
target
:
entityInfo
.
id
+
'
'
,
label
:
{
show
:
true
,
color
:
"#055fc2"
,
backgroundColor
:
"#eef7ff"
,
borderWidth
:
0
,
offset
:
[
0
,
15
],
formatter
:
item
.
relation
}
,
lineStyle
:
{
color
:
'#B9DCFF'
,
type
:
"solid"
,
opacity
:
1
}
}
}
const
onFormatNode
=
(
item
)
=>
{
let
leader
=
item
.
id
==
'0'
;
let
leader
=
item
.
id
==
entityInfo
.
id
;
return
{
id
:
item
.
id
+
''
,
name
:
onWordWrap
(
item
.
n
ame
,
7
),
name
:
onWordWrap
(
item
.
companyN
ame
,
7
),
label
:
{
show
:
true
,
color
:
"#3b414b"
,
...
...
@@ -269,7 +299,6 @@ const onWordWrap = (word, num) => {
onMounted
(()
=>
{
onDecreeEntities
();
initGraphChart
()
handleGetHylyList
();
}
);
<
/script
>
...
...
src/views/decree/decreeLayout/overview/introduction/index.vue
浏览文件 @
cfd54036
...
...
@@ -98,8 +98,8 @@
<div
class=
"box4"
>
<AnalysisBox
title=
"政令关键词云"
:showAllBtn=
"false"
>
<div
class=
"box4-main"
>
<el-empty
v-if=
"
false
"
description=
"暂无数据"
:image-size=
"100"
/>
<WordCloudChart
:data=
"wordCloudData"
width=
"100%"
height=
"100%"
/>
<el-empty
v-if=
"
!wordCloudData.length
"
description=
"暂无数据"
:image-size=
"100"
/>
<WordCloudChart
v-if=
"wordCloudData.length"
:data=
"wordCloudData"
width=
"100%"
height=
"100%"
/>
</div>
</AnalysisBox>
</div>
...
...
@@ -166,7 +166,8 @@ import WordCloudChart from "@/components/base/WordCloundChart/index.vue"
import
{
getDecreeBasicInfo
,
getDecreeRiskSignal
,
getDecreeIssueOrganization
getDecreeIssueOrganization
,
getKeyWordUp
,
}
from
"@/api/decree/introduction"
;
import
{
getDecreeRelatedEvent
}
from
"@/api/decree/background"
;
import
AiSummary
from
'@/components/base/Ai/AiSummary/index.vue'
...
...
@@ -230,19 +231,28 @@ const handleGetBasicInfo = async () => {
handleGetBasicInfo
();
// 政令关键词云
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
wordCloudData
=
ref
([
])
const
onKeyWordUp
=
async
()
=>
{
try
{
const
res
=
await
getKeyWordUp
();
console
.
log
(
"政令关键词云"
,
res
);
wordCloudData
.
value
=
res
.
data
.
slice
(
0
,
10
).
map
(
item
=>
({
name
:
item
.
name
,
value
:
item
.
count
}));
}
catch
(
error
)
{
console
.
error
(
"获取政令关键词云数据失败"
,
error
);
}
};
// 报告内容摘要
const
box1Data
=
ref
(
`包括经济竞争在内的美中竞争自2017年以来一直在定义美国外交政策。这两个经济体是世界上第一和第二大国家经济体,并且深深交织在一起。改变关系,无论多么必要,可能是昂贵的。因此,美国面临着一项挑战,确保其经济在耦合的战略竞争条件下满足国家的需求。为了应对这一挑战,兰德大学的研究人员对美中竞争进行了经济和制度分析,进行了参与式的远见练习,以了解确保美国经济健康的长期路径,并创建了两个经济竞争游戏,探索多个国家在相互交流的同时确保经济健康的动态...`
);
// const handleGetDecreeKeyInstruction = async () => {
// try {
// const res = await getDecreeKeyInstruction();
// console.log("报告内容摘要", res);
// box1Data.value = res.data;
// } catch (error) {
// console.error("获取报告内容摘要数据失败", error);
// }
// };
// 相关事件
const
relatedData
=
ref
([]);
...
...
@@ -332,6 +342,7 @@ const handleClickUser = item => {
};
onMounted
(()
=>
{
onKeyWordUp
()
onRiskSignalData
()
handleGetRelateEvents
();
handleGetOrgnization
();
...
...
src/views/decree/decreeOriginal/index.vue
浏览文件 @
cfd54036
...
...
@@ -41,10 +41,11 @@ import { getDecreeReport } from "@/api/decree/introduction";
import
BaseDecreeOriginal
from
"@/components/base/DecreeOriginal/index.vue"
;
const
route
=
useRoute
();
let
pdfUrl
=
""
;
const
handleDownload
=
async
()
=>
{
if
(
summaryInfo
.
value
?.
u
rl
)
{
if
(
pdfU
rl
)
{
try
{
const
response
=
await
fetch
(
summaryInfo
.
value
.
u
rl
,
{
const
response
=
await
fetch
(
pdfU
rl
,
{
method
:
'GET'
,
headers
:
{
'Content-Type'
:
'application/pdf'
},
});
...
...
@@ -103,6 +104,7 @@ const handleGetReport = async () => {
const
res
=
await
getDecreeReport
({
id
:
route
.
query
.
id
});
console
.
log
(
"报告原文"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
pdfUrl
=
res
.
data
.
pdfUrl
;
const
originData
=
[];
let
num
=
Math
.
max
(
res
.
data
.
content
.
length
,
res
.
data
.
contentEn
.
length
)
for
(
let
i
=
0
;
i
<
num
;
i
++
)
{
...
...
vite.config.js
浏览文件 @
cfd54036
...
...
@@ -44,16 +44,14 @@ export default defineConfig({
port
:
3000
,
open
:
true
,
proxy
:
{
'/reportData'
:
{
target
:
'http://8.140.26.4:10022/'
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
reportData/
,
''
)
},
'/api'
:
{
// target: 'http://8.140.26.4:9085/',
target
:
'http://1
72.20.10.3
:28080/'
,
target
:
'http://1
92.168.0.4
:28080/'
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api/
,
''
)
},
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论