Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
ff2aefac
提交
ff2aefac
authored
3月 24, 2026
作者:
张伊明
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix 修复aipane图表分析bug
fix 修复#17bug
上级
8fb13448
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
84 行增加
和
19 行删除
+84
-19
index.js
src/api/aiAnalysis/index.js
+14
-3
billHome.js
src/api/bill/billHome.js
+13
-0
index.vue
src/components/base/TipTab/index.vue
+8
-1
index.vue
src/views/bill/billHome/index.vue
+49
-15
没有找到文件。
src/api/aiAnalysis/index.js
浏览文件 @
ff2aefac
...
@@ -93,12 +93,23 @@ export function getChartAnalysis(data, options = {}) {
...
@@ -93,12 +93,23 @@ export function getChartAnalysis(data, options = {}) {
if
(
raw
===
"[DONE]"
)
return
;
if
(
raw
===
"[DONE]"
)
return
;
let
chunk
=
""
;
let
chunk
=
""
;
// 后端返回格式示例:{"text":"```"} / {"text":"json\n[\n"}
// 兼容后端返回格式:
// - {"text":"```"} / {"text":"json\n[\n"}
// - {"type":"reasoning","chunk":"..."}(新格式)
try
{
try
{
const
msg
=
JSON
.
parse
(
raw
);
const
msg
=
JSON
.
parse
(
raw
);
if
(
msg
&&
typeof
msg
===
"object"
&&
"text"
in
msg
)
{
if
(
Array
.
isArray
(
msg
?.
chunk
))
{
safeResolve
({
data
:
msg
.
chunk
});
abortController
.
abort
();
return
;
}
if
(
msg
&&
typeof
msg
===
"object"
&&
"chunk"
in
msg
)
{
chunk
=
typeof
msg
.
chunk
===
"string"
?
msg
.
chunk
:
""
;
if
(
chunk
)
buffer
+=
chunk
;
}
else
if
(
msg
&&
typeof
msg
===
"object"
&&
"text"
in
msg
)
{
chunk
=
String
(
msg
.
text
??
""
);
chunk
=
String
(
msg
.
text
??
""
);
buffer
+=
chunk
;
if
(
chunk
)
buffer
+=
chunk
;
}
else
{
}
else
{
chunk
=
raw
;
chunk
=
raw
;
buffer
+=
raw
;
buffer
+=
raw
;
...
...
src/api/bill/billHome.js
浏览文件 @
ff2aefac
...
@@ -28,6 +28,19 @@ export function getBillCount(params) {
...
@@ -28,6 +28,19 @@ export function getBillCount(params) {
})
})
}
}
// 近期美国国会各委员会涉华提案数量汇总
/**
* @param {Object} params
* @param {string} params.dateDesc - 时间范围:近一周/近一月/近一年
*/
export
function
getStatisticsBillCountByCommittee
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/BillOverview/statisticsBillCountByCommittee`
,
params
})
}
// 获取关键条款
// 获取关键条款
export
function
getBillOverviewKeyTK
()
{
export
function
getBillOverviewKeyTK
()
{
return
request
({
return
request
({
...
...
src/components/base/TipTab/index.vue
浏览文件 @
ff2aefac
...
@@ -3,13 +3,18 @@
...
@@ -3,13 +3,18 @@
<div
class=
"icon"
>
<div
class=
"icon"
>
<img
src=
"./tip-icon.svg"
alt=
""
>
<img
src=
"./tip-icon.svg"
alt=
""
>
</div>
</div>
<div
class=
"text text-tip-2 text-primary-50-clor"
>
{{
`数据来源:${dataSource
}
,数据时间:${dataTime
}
`
}}
<
/div
>
<div
class=
"text text-tip-2 text-primary-50-clor"
>
{{
tipText
}}
</div>
</div>
</div>
</
template
>
</
template
>
<
script
setup
>
<
script
setup
>
import
{
computed
}
from
'vue'
const
props
=
defineProps
({
const
props
=
defineProps
({
text
:
{
type
:
String
,
default
:
''
},
dataSource
:
{
dataSource
:
{
type
:
String
,
type
:
String
,
default
:
'美国国会官网'
default
:
'美国国会官网'
...
@@ -21,6 +26,8 @@ const props = defineProps({
...
@@ -21,6 +26,8 @@ const props = defineProps({
})
})
const
tipText
=
computed
(()
=>
props
.
text
||
`数据来源:
${
props
.
dataSource
}
,数据时间:
${
props
.
dataTime
}
`
)
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
...
...
src/views/bill/billHome/index.vue
浏览文件 @
ff2aefac
...
@@ -131,7 +131,7 @@
...
@@ -131,7 +131,7 @@
<DivideHeader
id=
"position3"
class=
"divide3"
:titleText=
"'数据总览'"
></DivideHeader>
<DivideHeader
id=
"position3"
class=
"divide3"
:titleText=
"'数据总览'"
></DivideHeader>
<div
class=
"center-footer"
>
<div
class=
"center-footer"
>
<OverviewCard
class=
"overview-card--double box5"
title=
"
涉华法案
数量变化趋势"
:icon=
"box5HeaderIcon"
>
<OverviewCard
class=
"overview-card--double box5"
title=
"数量变化趋势"
:icon=
"box5HeaderIcon"
>
<
template
#
right
>
<
template
#
right
>
<el-select
v-model=
"box5Select"
placeholder=
"选择领域"
@
change=
"handleBox5Change"
<el-select
v-model=
"box5Select"
placeholder=
"选择领域"
@
change=
"handleBox5Change"
style=
"width: 150px"
>
style=
"width: 150px"
>
...
@@ -151,7 +151,7 @@
...
@@ -151,7 +151,7 @@
<div
v-else
id=
"box5Chart"
class=
"overview-chart"
></div>
<div
v-else
id=
"box5Chart"
class=
"overview-chart"
></div>
</div>
</div>
<div
class=
"overview-tip-row"
>
<div
class=
"overview-tip-row"
>
<TipTab
class=
"overview-tip"
/>
<TipTab
class=
"overview-tip"
:text=
"'图表说明:xxxxx,数据来源:美国国会官网'"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box5')"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box5')"
/>
</div>
</div>
<div
v-if=
"aiPaneVisible.box5"
class=
"overview-ai-pane"
<div
v-if=
"aiPaneVisible.box5"
class=
"overview-ai-pane"
...
@@ -160,7 +160,7 @@
...
@@ -160,7 +160,7 @@
</div>
</div>
</div>
</div>
</OverviewCard>
</OverviewCard>
<OverviewCard
class=
"overview-card--single box6"
title=
"
涉华法案领域分布
"
:icon=
"box6HeaderIcon"
>
<OverviewCard
class=
"overview-card--single box6"
title=
"
领域分布情况
"
:icon=
"box6HeaderIcon"
>
<
template
#
right
>
<
template
#
right
>
<el-select
v-model=
"box9selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-select
v-model=
"box9selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-option
v-for=
"item in box9YearList"
:key=
"item.value"
:label=
"item.label"
<el-option
v-for=
"item in box9YearList"
:key=
"item.value"
:label=
"item.label"
...
@@ -178,7 +178,7 @@
...
@@ -178,7 +178,7 @@
<div
v-else
id=
"box9Chart"
class=
"overview-chart"
></div>
<div
v-else
id=
"box9Chart"
class=
"overview-chart"
></div>
</div>
</div>
<div
class=
"overview-tip-row"
>
<div
class=
"overview-tip-row"
>
<TipTab
class=
"overview-tip"
/>
<TipTab
class=
"overview-tip"
:text=
"'图表说明:xxxxx,数据来源:美国国会官网'"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box6')"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box6')"
/>
</div>
</div>
<div
v-if=
"aiPaneVisible.box6"
class=
"overview-ai-pane"
<div
v-if=
"aiPaneVisible.box6"
class=
"overview-ai-pane"
...
@@ -189,7 +189,7 @@
...
@@ -189,7 +189,7 @@
</OverviewCard>
</OverviewCard>
</div>
</div>
<div
class=
"center-footer1"
>
<div
class=
"center-footer1"
>
<OverviewCard
class=
"overview-card--single box7"
title=
"
涉华法案提出部门
"
:icon=
"box7HeaderIcon"
>
<OverviewCard
class=
"overview-card--single box7"
title=
"
提案委员会分布情况
"
:icon=
"box7HeaderIcon"
>
<
template
#
right
>
<
template
#
right
>
<el-select
v-model=
"box7selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-select
v-model=
"box7selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-option
v-for=
"item in box7YearList"
:key=
"item.value"
:label=
"item.label"
<el-option
v-for=
"item in box7YearList"
:key=
"item.value"
:label=
"item.label"
...
@@ -202,7 +202,7 @@
...
@@ -202,7 +202,7 @@
<div
v-else
id=
"box7Chart"
class=
"overview-chart"
></div>
<div
v-else
id=
"box7Chart"
class=
"overview-chart"
></div>
</div>
</div>
<div
class=
"overview-tip-row"
>
<div
class=
"overview-tip-row"
>
<TipTab
class=
"overview-tip"
/>
<TipTab
class=
"overview-tip"
:text=
"'图表说明:xxxxx,数据来源:美国国会官网'"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box7')"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box7')"
/>
</div>
</div>
<div
v-if=
"aiPaneVisible.box7"
class=
"overview-ai-pane"
<div
v-if=
"aiPaneVisible.box7"
class=
"overview-ai-pane"
...
@@ -211,7 +211,7 @@
...
@@ -211,7 +211,7 @@
</div>
</div>
</div>
</div>
</OverviewCard>
</OverviewCard>
<OverviewCard
class=
"overview-card--single box8"
title=
"
涉华法案进展分布
"
:icon=
"box7HeaderIcon"
>
<OverviewCard
class=
"overview-card--single box8"
title=
"
进展分布情况
"
:icon=
"box7HeaderIcon"
>
<
template
#
right
>
<
template
#
right
>
<el-select
v-model=
"box8selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-select
v-model=
"box8selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-option
v-for=
"item in box8YearList"
:key=
"item.value"
:label=
"item.label"
<el-option
v-for=
"item in box8YearList"
:key=
"item.value"
:label=
"item.label"
...
@@ -227,7 +227,7 @@
...
@@ -227,7 +227,7 @@
</
template
>
</
template
>
</div>
</div>
<div
class=
"overview-tip-row"
>
<div
class=
"overview-tip-row"
>
<TipTab
class=
"overview-tip"
/>
<TipTab
class=
"overview-tip"
:text=
"'图表说明:xxxxx,数据来源:美国国会官网'"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box8')"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box8')"
/>
</div>
</div>
<div
v-if=
"aiPaneVisible.box8"
class=
"overview-ai-pane"
<div
v-if=
"aiPaneVisible.box8"
class=
"overview-ai-pane"
...
@@ -236,7 +236,7 @@
...
@@ -236,7 +236,7 @@
</div>
</div>
</div>
</div>
</OverviewCard>
</OverviewCard>
<OverviewCard
class=
"overview-card--single box9"
title=
"
涉华法案关键条款
"
:icon=
"box7HeaderIcon"
>
<OverviewCard
class=
"overview-card--single box9"
title=
"
关键条款词云
"
:icon=
"box7HeaderIcon"
>
<div
class=
"overview-card-body box9-main"
>
<div
class=
"overview-card-body box9-main"
>
<div
class=
"overview-chart-wrap"
>
<div
class=
"overview-chart-wrap"
>
<el-empty
v-if=
"!wordCloudHasData"
description=
"暂无数据"
:image-size=
"100"
/>
<el-empty
v-if=
"!wordCloudHasData"
description=
"暂无数据"
:image-size=
"100"
/>
...
@@ -244,7 +244,7 @@
...
@@ -244,7 +244,7 @@
:data=
"wordCloudData"
/>
:data=
"wordCloudData"
/>
</div>
</div>
<div
class=
"overview-tip-row"
>
<div
class=
"overview-tip-row"
>
<TipTab
class=
"overview-tip"
/>
<TipTab
class=
"overview-tip"
:text=
"'图表说明:xxxxx,数据来源:美国国会官网'"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box9')"
/>
<AiButton
class=
"overview-tip-action"
@
mouseenter=
"handleShowAiPane('box9')"
/>
</div>
</div>
<div
v-if=
"aiPaneVisible.box9"
class=
"overview-ai-pane"
<div
v-if=
"aiPaneVisible.box9"
class=
"overview-ai-pane"
...
@@ -276,6 +276,7 @@ import {
...
@@ -276,6 +276,7 @@ import {
getBillRiskSignal
,
getBillRiskSignal
,
getHylyList
,
getHylyList
,
getBillOverviewKeyTK
,
getBillOverviewKeyTK
,
getStatisticsBillCountByCommittee
,
getBillCount
,
getBillCount
,
getBillPostOrg
,
getBillPostOrg
,
getBillProcess
,
getBillProcess
,
...
@@ -371,11 +372,36 @@ const committeeTimeOptions = [
...
@@ -371,11 +372,36 @@ const committeeTimeOptions = [
{
label
:
"近一月"
,
value
:
"近一月"
},
{
label
:
"近一月"
,
value
:
"近一月"
},
{
label
:
"近一年"
,
value
:
"近一年"
}
{
label
:
"近一年"
,
value
:
"近一年"
}
];
];
const
committeeCardList
=
ref
([
const
committeeCardList
=
ref
([]);
{
id
:
1
,
name
:
"众议院外交委员会"
,
chamber
:
"众议院"
,
count
:
42
},
{
id
:
2
,
name
:
"参议院军事委员会"
,
chamber
:
"参议院"
,
count
:
28
},
const
getChamberLabel
=
orgType
=>
{
{
id
:
3
,
name
:
"众议院情报委员会"
,
chamber
:
"众议院"
,
count
:
19
}
if
(
orgType
===
"Senate"
)
return
"参议院"
;
]);
if
(
orgType
===
"House"
)
return
"众议院"
;
return
orgType
||
""
;
};
const
handleGetCommitteeBillCount
=
async
()
=>
{
try
{
const
res
=
await
getStatisticsBillCountByCommittee
({
dateDesc
:
committeeTimeRange
.
value
});
if
(
res
.
code
===
200
&&
Array
.
isArray
(
res
.
data
))
{
committeeCardList
.
value
=
res
.
data
.
map
(
item
=>
({
id
:
`
${
item
.
orgType
||
""
}
-
${
item
.
orgName
||
""
}
`
,
name
:
item
.
orgName
,
chamber
:
getChamberLabel
(
item
.
orgType
),
count
:
Number
(
item
.
count
||
0
)
}))
.
sort
((
a
,
b
)
=>
(
b
.
count
||
0
)
-
(
a
.
count
||
0
))
.
slice
(
0
,
3
);
}
else
{
committeeCardList
.
value
=
[];
}
}
catch
(
error
)
{
committeeCardList
.
value
=
[];
}
};
const
hotBillList
=
ref
([]);
// 热门法案列表
const
hotBillList
=
ref
([]);
// 热门法案列表
const
carouselRef
=
ref
(
null
);
const
carouselRef
=
ref
(
null
);
...
@@ -1191,6 +1217,14 @@ watch(box8selectetedTime, () => {
...
@@ -1191,6 +1217,14 @@ watch(box8selectetedTime, () => {
handleBox8Data
();
handleBox8Data
();
});
});
watch
(
committeeTimeRange
,
()
=>
{
handleGetCommitteeBillCount
();
},
{
immediate
:
true
}
);
const
handleToPosi
=
id
=>
{
const
handleToPosi
=
id
=>
{
const
element
=
document
.
getElementById
(
id
);
const
element
=
document
.
getElementById
(
id
);
if
(
element
&&
containerRef
.
value
)
{
if
(
element
&&
containerRef
.
value
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论