Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
48e24d11
提交
48e24d11
authored
3月 31, 2026
作者:
张伊明
浏览文件
操作
浏览文件
下载
差异文件
合并分支 'zym-dev' 到 'pre'
feat 法案首页新增loading,更改法案阶段字典 查看合并请求
!286
上级
094f43e3
a71756d8
流水线
#246
已通过 于阶段
in 4 分 25 秒
变更
7
流水线
1
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
176 行增加
和
94 行删除
+176
-94
index.js
src/api/aiAnalysis/index.js
+17
-0
bill.js
src/api/bill.js
+8
-4
billHome.js
src/api/bill/billHome.js
+8
-2
index.vue
src/views/bill/billHome/index.vue
+59
-29
multiLineChart.js
src/views/bill/billHome/utils/multiLineChart.js
+14
-9
BillHeader.vue
src/views/bill/billLayout/components/BillHeader.vue
+19
-43
index.vue
src/views/bill/template/index.vue
+51
-7
没有找到文件。
src/api/aiAnalysis/index.js
浏览文件 @
48e24d11
...
...
@@ -143,6 +143,7 @@ export function getChartAnalysis(data, options = {}) {
: typeof options?.onInterpretationDelta === "function"
? options.onInterpretationDelta
: null;
const externalSignal = options?.signal;
return new Promise((resolve, reject) => {
let buffer = "";
let latestInterpretation = "";
...
...
@@ -150,16 +151,32 @@ export function getChartAnalysis(data, options = {}) {
let lastStreamedInterpretationLen = 0;
let settled = false;
const abortController = new AbortController();
const externalAbortHandler = () => {
abortController.abort();
};
if (externalSignal) {
if (externalSignal.aborted) {
abortController.abort();
} else {
externalSignal.addEventListener("abort", externalAbortHandler, { once: true });
}
}
const safeResolve = value => {
if (settled) return;
settled = true;
if (externalSignal) {
externalSignal.removeEventListener("abort", externalAbortHandler);
}
resolve(value);
};
const safeReject = err => {
if (settled) return;
settled = true;
if (externalSignal) {
externalSignal.removeEventListener("abort", externalAbortHandler);
}
reject(err);
};
...
...
src/api/bill.js
浏览文件 @
48e24d11
...
...
@@ -107,11 +107,12 @@ export function getBillPersonAnalyzeDy(params) {
* @param {id}
* @header token
*/
export
function
getBillContentId
(
params
)
{
export
function
getBillContentId
(
params
,
config
=
{}
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/billInfoBean/contentId/
${
params
.
id
}
`
,
params
,
signal
:
config
.
signal
})
}
...
...
@@ -120,11 +121,12 @@ export function getBillContentId(params) {
* @param {billId,id,cRelated,currentPage,pageSize,domainNameList,measuresNameList,content}
* @header token
*/
export
function
getBillContentTk
(
params
)
{
export
function
getBillContentTk
(
params
,
config
=
{}
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/billInfoBean/content/tk/
${
params
.
billId
}
/
${
params
.
id
}
`
,
params
,
signal
:
config
.
signal
})
}
...
...
@@ -133,11 +135,12 @@ export function getBillContentTk(params) {
* @param {billId,versionId,cRelated}
* @header token
*/
export
function
getBillContentXzfs
(
params
)
{
export
function
getBillContentXzfs
(
params
,
config
=
{}
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/billInfoBean/content/xzfs/
${
params
.
billId
}
/
${
params
.
versionId
}
`
,
params
,
signal
:
config
.
signal
})
}
...
...
@@ -146,11 +149,12 @@ export function getBillContentXzfs(params) {
* @param {billId,versionId,cRelated}
* @header token
*/
export
function
getBillHyly
(
params
)
{
export
function
getBillHyly
(
params
,
config
=
{}
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/billInfoBean/content/hyly/
${
params
.
billId
}
/
${
params
.
versionId
}
`
,
params
,
signal
:
config
.
signal
})
}
...
...
src/api/bill/billHome.js
浏览文件 @
48e24d11
...
...
@@ -3,8 +3,14 @@ import request from "@/api/request.js";
// 涉华法案领域分布
/**
* @param {Object} params
* @param {string} params.year - 年份
* @param {string} [params.status] - 状态:提出法案/通过法案
* @param {string} params.year - 年份(2022-2026)
* @param {string} [params.status] - 法案状态:
* - 提案
* - 众议院通过
* - 参议院通过
* - 分歧已解决
* - 呈交总统
* - 完成立法
*/
export
function
getBillIndustry
(
params
)
{
return
request
({
...
...
src/views/bill/billHome/index.vue
浏览文件 @
48e24d11
...
...
@@ -144,7 +144,7 @@
</el-select>
</
template
>
<div
class=
"overview-card-body box5-main"
>
<div
class=
"overview-chart-wrap"
:class=
"{ 'is-empty': !box5HasData }"
>
<div
class=
"overview-chart-wrap"
v-loading=
"chartLoading.box5"
:class=
"{ 'is-empty': !box5HasData }"
>
<el-empty
v-if=
"!box5HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box5Chart"
class=
"overview-chart"
></div>
</div>
...
...
@@ -169,7 +169,7 @@
</el-select>
</
template
>
<div
class=
"overview-card-body box6-main"
>
<div
class=
"overview-chart-wrap"
:class=
"{ 'is-empty': !box9HasData }"
>
<div
class=
"overview-chart-wrap"
v-loading=
"chartLoading.box6"
:class=
"{ 'is-empty': !box9HasData }"
>
<el-empty
v-if=
"!box9HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box9Chart"
class=
"overview-chart"
></div>
</div>
...
...
@@ -191,7 +191,7 @@
</el-select>
</
template
>
<div
class=
"overview-card-body box7-main"
>
<div
class=
"overview-chart-wrap"
:class=
"{ 'is-empty': !box7HasData }"
>
<div
class=
"overview-chart-wrap"
v-loading=
"chartLoading.box7"
:class=
"{ 'is-empty': !box7HasData }"
>
<el-empty
v-if=
"!box7HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box7Chart"
class=
"overview-chart"
></div>
</div>
...
...
@@ -211,10 +211,10 @@
</el-select>
</
template
>
<div
class=
"overview-card-body box8-main"
>
<div
class=
"overview-chart-wrap"
:class=
"{ 'is-empty': !box8HasData }"
>
<div
class=
"overview-chart-wrap"
v-loading=
"chartLoading.box8"
:class=
"{ 'is-empty': !box8HasData }"
>
<el-empty
v-if=
"!box8HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<
template
v-else
>
<div
class=
"box8-desc"
>
•
通过
涉华法案
{{
box8Summary
}}
项
</div>
<div
class=
"box8-desc"
>
•
完成立法
涉华法案
{{
box8Summary
}}
项
</div>
<div
id=
"box8Chart"
class=
"overview-chart box8-chart"
></div>
</
template
>
</div>
...
...
@@ -229,7 +229,7 @@
</OverviewCard>
<OverviewCard
class=
"overview-card--single box9"
title=
"关键条款词云"
:icon=
"box7HeaderIcon"
>
<div
class=
"overview-card-body box9-main"
>
<div
class=
"overview-chart-wrap"
>
<div
class=
"overview-chart-wrap"
v-loading=
"chartLoading.box9"
>
<el-empty
v-if=
"!wordCloudHasData"
description=
"暂无数据"
:image-size=
"100"
/>
<WordCloundChart
v-else
class=
"overview-chart"
width=
"100%"
height=
"100%"
:data=
"wordCloudData"
/>
</div>
...
...
@@ -512,6 +512,14 @@ const aiPaneLoading = ref({
box9
:
false
});
const
chartLoading
=
ref
({
box5
:
false
,
box6
:
false
,
box7
:
false
,
box8
:
false
,
box9
:
false
});
const
gotoNewsDetail
=
useGotoNewsDetail
();
const
handleClickNewsDetail
=
news
=>
{
const
newsId
=
news
?.
newsId
||
news
?.
id
;
...
...
@@ -767,7 +775,7 @@ const box5Data = ref({
value
:
[
145
,
52
,
84
,
99
,
71
,
96
,
128
,
144
,
140
,
168
,
188
,
172
]
},
{
name
:
"
通过法案
"
,
name
:
"
完成立法
"
,
value
:
[
6
,
3
,
4
,
6
,
11
,
5
,
2
,
14
,
16
,
27
,
28
,
44
]
},
{
...
...
@@ -779,13 +787,14 @@ const box5Data = ref({
value
:
[]
},
{
name
:
"
双院通过
"
,
name
:
"
解决分歧
"
,
value
:
[]
}
]
});
const
box5HasData
=
ref
(
true
);
const
handleGetBillCount
=
async
()
=>
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box5
:
true
};
try
{
const
params
=
{
dateDesc
:
box5ProposalTime
.
value
...
...
@@ -806,7 +815,7 @@ const handleGetBillCount = async () => {
value
:
sortedData
.
map
(
item
=>
item
.
proposedCount
)
},
{
name
:
"
通过法案
"
,
name
:
"
完成立法
"
,
value
:
sortedData
.
map
(
item
=>
item
.
passCount
)
},
{
...
...
@@ -818,7 +827,7 @@ const handleGetBillCount = async () => {
value
:
sortedData
.
map
(
item
=>
item
.
senateCount
)
},
{
name
:
"
双院通过
"
,
name
:
"
解决分歧
"
,
value
:
sortedData
.
map
(
item
=>
item
.
hscount
)
}
],
...
...
@@ -831,10 +840,10 @@ const handleGetBillCount = async () => {
title
:
[],
data
:
[
{
name
:
"提出法案"
,
value
:
[]
},
{
name
:
"
通过法案
"
,
value
:
[]
},
{
name
:
"
完成立法
"
,
value
:
[]
},
{
name
:
"众议院通过"
,
value
:
[]
},
{
name
:
"参议院通过"
,
value
:
[]
},
{
name
:
"
双院通过
"
,
value
:
[]
}
{
name
:
"
解决分歧
"
,
value
:
[]
}
],
percent
:
[]
};
...
...
@@ -847,13 +856,15 @@ const handleGetBillCount = async () => {
title
:
[],
data
:
[
{
name
:
"提出法案"
,
value
:
[]
},
{
name
:
"
通过法案
"
,
value
:
[]
},
{
name
:
"
完成立法
"
,
value
:
[]
},
{
name
:
"众议院通过"
,
value
:
[]
},
{
name
:
"参议院通过"
,
value
:
[]
},
{
name
:
"
双院通过
"
,
value
:
[]
}
{
name
:
"
解决分歧
"
,
value
:
[]
}
],
percent
:
[]
};
}
finally
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box5
:
false
};
}
};
...
...
@@ -893,6 +904,7 @@ const handleBox5Change = () => {
const
box7HasData
=
ref
(
true
);
const
box7AiData
=
ref
({
inner
:
[],
outer
:
[]
});
const
handleBox7Data
=
async
()
=>
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box7
:
true
};
try
{
const
res
=
await
getBillPostOrg
({
year
:
box7selectetedTime
.
value
});
console
.
log
(
"法案提出部门"
,
res
);
...
...
@@ -946,6 +958,8 @@ const handleBox7Data = async () => {
console
.
error
(
"获取法案提出部门数据失败"
,
error
);
box7HasData
.
value
=
false
;
box7AiData
.
value
=
{
inner
:
[],
outer
:
[]
};
}
finally
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box7
:
false
};
}
};
...
...
@@ -972,6 +986,7 @@ const handleToSocialDetail = item => {
const
wordCloudData
=
ref
([]);
const
wordCloudHasData
=
computed
(()
=>
Array
.
isArray
(
wordCloudData
.
value
)
&&
wordCloudData
.
value
.
length
>
0
);
const
handleGetKeyTK
=
async
()
=>
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box9
:
true
};
try
{
const
res
=
await
getBillOverviewKeyTK
();
console
.
log
(
"关键条款"
,
res
);
...
...
@@ -989,6 +1004,8 @@ const handleGetKeyTK = async () => {
}
}
catch
(
error
)
{
console
.
error
(
"获取关键条款error"
,
error
);
}
finally
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box9
:
false
};
}
};
const
handleBox6
=
async
()
=>
{
...
...
@@ -998,10 +1015,15 @@ const handleBox6 = async () => {
// 涉华领域分布
const
box9ChartData
=
ref
([]);
const
box9selectetedTime
=
ref
(
"2025"
);
const
box9LegislativeStatus
=
ref
(
"提出法案"
);
// 立法状态下拉:提出法案、众议院通过、参议院通过、解决分歧、完成立法
// v-model 存储的是接口需要的 status 值
const
box9LegislativeStatus
=
ref
(
"提案"
);
const
box9LegislativeStatusList
=
ref
([
{
label
:
"提出法案"
,
value
:
"提出法案"
},
{
label
:
"通过法案"
,
value
:
"通过法案"
}
{
label
:
"提出法案"
,
value
:
"提案"
},
{
label
:
"众议院通过"
,
value
:
"众议院通过"
},
{
label
:
"参议院通过"
,
value
:
"参议院通过"
},
{
label
:
"解决分歧"
,
value
:
"分歧已解决"
},
{
label
:
"完成立法"
,
value
:
"完成立法"
}
]);
const
box9YearList
=
ref
([
{
...
...
@@ -1028,6 +1050,7 @@ const box9YearList = ref([
const
box9HasData
=
ref
(
true
);
let
box9ChartInstance
=
null
;
const
getBox9Data
=
async
()
=>
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box6
:
true
};
const
params
=
{
year
:
box9selectetedTime
.
value
,
status
:
box9LegislativeStatus
.
value
...
...
@@ -1045,6 +1068,8 @@ const getBox9Data = async () => {
}
catch
(
error
)
{
box9HasData
.
value
=
false
;
box9ChartData
.
value
=
[];
}
finally
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box6
:
false
};
}
};
const
handleBox9Data
=
async
()
=>
{
...
...
@@ -1061,11 +1086,15 @@ const handleBox9Data = async () => {
null
,
{
showCount
:
false
}
);
// 记录埋点时,将当前选中的立法状态映射为序号(0-4)
const
selectedIndex
=
box9LegislativeStatusList
.
value
.
findIndex
(
item
=>
item
.
value
===
box9LegislativeStatus
.
value
);
const
selectParam
=
{
moduleType
:
'国会法案'
,
key
:
'领域'
,
selectedDate
:
box9selectetedTime
.
value
,
selectedStatus
:
box9LegislativeStatus
.
value
===
'提出法案'
?
0
:
1
,
selectedStatus
:
selectedIndex
,
isInvolveCn
:
1
}
box9ChartInstance
=
setChart
(
box9Chart
,
"box9Chart"
,
true
,
selectParam
);
...
...
@@ -1088,14 +1117,13 @@ const box8StageList = ref([]);
const
box8MockDataByYear
=
{
"2025"
:
{
passCount
:
19
,
// 从上到下顺序:提出法案、众议院通过、参议院通过、解决分歧、完成立法
stages
:
[
{
name
:
"
已提
案"
,
count
:
24
},
{
name
:
"
提出法
案"
,
count
:
24
},
{
name
:
"众议院通过"
,
count
:
20
},
{
name
:
"众议院不通过"
,
count
:
25
},
{
name
:
"解决分歧"
,
count
:
23
},
{
name
:
"参议院通过"
,
count
:
26
},
{
name
:
"
总统否决"
,
count
:
48
},
{
name
:
"
已
立法"
,
count
:
19
}
{
name
:
"
解决分歧"
,
count
:
23
},
{
name
:
"
完成
立法"
,
count
:
19
}
]
}
};
...
...
@@ -1219,15 +1247,15 @@ const getBox8ChartOption = stageList => {
};
const
handleBox8Data
=
async
()
=>
{
const
stageOrder
=
[
"提案"
,
"众议院通过"
,
"众议院不通过"
,
"分歧已解决"
,
"参议院通过"
,
"总统否决或未签署"
,
"完成立法"
];
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box8
:
true
};
// 进展分布显示顺序:提出法案(对应进度“提案”)、众议院通过、参议院通过、分歧已解决(解决分歧)、完成立法
const
stageOrder
=
[
"提案"
,
"众议院通过"
,
"参议院通过"
,
"分歧已解决"
,
"完成立法"
];
const
stageNameMap
=
{
提案
:
"
已提
案"
,
提案
:
"
提出法
案"
,
众议院通过
:
"众议院通过"
,
众议院不通过
:
"众议院不通过"
,
分歧已解决
:
"解决分歧"
,
参议院通过
:
"参议院通过"
,
"总统否决或未签署"
:
"总统否决
"
,
完成立法
:
"
已
立法"
分歧已解决
:
"解决分歧
"
,
完成立法
:
"
完成
立法"
};
try
{
...
...
@@ -1286,6 +1314,8 @@ const handleBox8Data = async () => {
box8StageList
.
value
=
[];
setChart
({},
"box8Chart"
,
true
,
selectParam
);
}
}
finally
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box8
:
false
};
}
};
...
...
src/views/bill/billHome/utils/multiLineChart.js
浏览文件 @
48e24d11
...
...
@@ -49,7 +49,8 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
containLabel
:
true
},
legend
:
{
data
:
[
'提出法案'
,
'通过法案'
,
'众议院通过'
,
'参议院通过'
,
'双院通过'
],
// 图例顺序:提出法案、众议院通过、参议院通过、解决分歧、完成立法
data
:
[
'提出法案'
,
'众议院通过'
,
'参议院通过'
,
'解决分歧'
,
'完成立法'
],
show
:
true
,
top
:
10
,
icon
:
'circle'
,
...
...
@@ -126,7 +127,8 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
data
:
proposedData
},
{
name
:
'通过法案'
,
// 众议院通过
name
:
'众议院通过'
,
type
:
'line'
,
smooth
:
true
,
symbol
:
'emptyCircle'
,
...
...
@@ -137,10 +139,11 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
itemStyle
:
{
color
:
lineColors
[
1
]
},
data
:
pass
Data
data
:
house
Data
},
{
name
:
'众议院通过'
,
// 参议院通过
name
:
'参议院通过'
,
type
:
'line'
,
smooth
:
true
,
symbol
:
'emptyCircle'
,
...
...
@@ -151,10 +154,11 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
itemStyle
:
{
color
:
lineColors
[
2
]
},
data
:
hous
eData
data
:
senat
eData
},
{
name
:
'参议院通过'
,
// 解决分歧
name
:
'解决分歧'
,
type
:
'line'
,
smooth
:
true
,
symbol
:
'emptyCircle'
,
...
...
@@ -165,10 +169,11 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
itemStyle
:
{
color
:
lineColors
[
3
]
},
data
:
senate
Data
data
:
hs
Data
},
{
name
:
'双院通过'
,
// 完成立法
name
:
'完成立法'
,
type
:
'line'
,
smooth
:
true
,
symbol
:
'emptyCircle'
,
...
...
@@ -179,7 +184,7 @@ const getMultiLineChart = (dataX, proposedData, passData, houseData, senateData,
itemStyle
:
{
color
:
lineColors
[
4
]
},
data
:
h
sData
data
:
pas
sData
}
]
}
...
...
src/views/bill/billLayout/components/BillHeader.vue
浏览文件 @
48e24d11
...
...
@@ -27,29 +27,17 @@
</div>
<div
class=
"left-box-bottom"
v-if=
"showTabs"
>
<
template
v-if=
"isLoading"
>
<div
class=
"left-box-bottom-item is-skeleton"
v-for=
"n in 4"
:key=
"n"
>
<div
class=
"icon"
>
<el-skeleton-item
class=
"skeleton-tab-icon"
variant=
"text"
/>
</div>
<div
class=
"name"
>
<el-skeleton-item
class=
"skeleton-tab-text"
variant=
"text"
/>
</div>
<div
class=
"left-box-bottom-item"
:class=
"{ leftBoxBottomItemActive: activeTitle === item.name }"
v-for=
"item in tabs"
:key=
"item.path"
@
click=
"emit('tab-click', item)"
>
<div
class=
"icon"
>
<img
v-if=
"activeTitle === item.name"
:src=
"item.activeIcon"
alt=
""
/>
<img
v-else
:src=
"item.icon"
alt=
""
/>
</div>
</
template
>
<
template
v-else
>
<div
class=
"left-box-bottom-item"
:class=
"
{ leftBoxBottomItemActive: activeTitle === item.name }" v-for="item in tabs"
:key="item.path" @click="emit('tab-click', item)">
<div
class=
"icon"
>
<img
v-if=
"activeTitle === item.name"
:src=
"item.activeIcon"
alt=
""
/>
<img
v-else
:src=
"item.icon"
alt=
""
/>
</div>
<div
class=
"name"
:class=
"
{ nameActive: activeTitle === item.name }">
{{
item
.
name
}}
</div>
<div
class=
"name"
:class=
"{ nameActive: activeTitle === item.name }"
>
{{ item.name }}
</div>
</
template
>
</
div
>
</div>
</div>
...
...
@@ -73,30 +61,18 @@
</div>
<div
class=
"right-box-bottom"
v-if=
"showActions"
>
<
template
v-if=
"isLoading"
>
<div
class=
"btn3 is-skeleton"
>
<div
class=
"icon"
>
<el-skeleton-item
class=
"skeleton-action-icon"
variant=
"text"
/>
</div>
<div
class=
"text"
>
<el-skeleton-item
class=
"skeleton-action-text"
variant=
"text"
/>
</div>
<div
class=
"btn2"
@
click=
"emit('open-analysis', 'forsee')"
>
<div
class=
"icon"
>
<img
:src=
"btnIconForsee"
alt=
""
/>
</div>
</
template
>
<
template
v-else
>
<div
class=
"btn2"
@
click=
"emit('open-analysis', 'forsee')"
>
<div
class=
"icon"
>
<img
:src=
"btnIconForsee"
alt=
""
/>
</div>
<div
class=
"text"
>
{{
"进展预测"
}}
</div>
</div>
<div
class=
"btn3"
@
click=
"emit('open-analysis', 'analysis')"
>
<div
class=
"icon"
>
<img
:src=
"btnIconAnalysis"
alt=
""
/>
</div>
<div
class=
"text"
>
{{
"分析报告"
}}
</div>
<div
class=
"text"
>
{{ "进展预测" }}
</div>
</div>
<div
class=
"btn3"
@
click=
"emit('open-analysis', 'analysis')"
>
<div
class=
"icon"
>
<img
:src=
"btnIconAnalysis"
alt=
""
/>
</div>
</
template
>
<div
class=
"text"
>
{{ "分析报告" }}
</div>
</div>
</div>
</div>
</div>
...
...
src/views/bill/template/index.vue
浏览文件 @
48e24d11
...
...
@@ -150,8 +150,8 @@
</template>
<
script
setup
>
import
{
ref
,
onMounted
,
computed
,
watch
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
ref
,
onMounted
,
onBeforeUnmount
,
computed
,
watch
}
from
"vue"
;
import
{
useRoute
,
onBeforeRouteLeave
}
from
"vue-router"
;
import
*
as
echarts
from
"echarts"
;
import
{
Search
}
from
"@element-plus/icons-vue"
;
import
getPieChart
from
"./utils/piechart"
;
...
...
@@ -165,6 +165,31 @@ import { extractTextEntity } from "@/api/intelligent/index";
const
route
=
useRoute
();
const
pageAbortController
=
new
AbortController
();
const
isRequestCanceled
=
error
=>
{
return
(
error
?.
code
===
"ERR_CANCELED"
||
error
?.
name
===
"CanceledError"
||
error
?.
name
===
"AbortError"
||
(
typeof
error
?.
message
===
"string"
&&
/canceled|aborted/i
.
test
(
error
.
message
))
);
};
const
getPageSignal
=
()
=>
pageAbortController
.
signal
;
const
stopCurrentPageRequests
=
()
=>
{
pageAbortController
.
abort
();
// 让旧请求回调全部失效,避免离开页面后回写状态
tkRequestToken
.
value
+=
1
;
xzfsRequestToken
.
value
+=
1
;
hylyRequestToken
.
value
+=
1
;
entityRequestToken
.
value
+=
1
;
termsLoading
.
value
=
false
;
limitLoading
.
value
=
false
;
domainLoading
.
value
=
false
;
aiPaneLoading
.
value
=
{
domain
:
false
,
limit
:
false
};
};
const
curBill
=
ref
(
""
);
const
curBillId
=
ref
(
null
);
...
...
@@ -294,7 +319,7 @@ const ensureEntitiesForTerms = async terms => {
try
{
const
results
=
await
Promise
.
all
(
tasks
.
map
(
async
item
=>
{
const
res
=
await
extractTextEntity
(
item
.
text
);
const
res
=
await
extractTextEntity
(
item
.
text
,
{
signal
:
getPageSignal
()
}
);
const
entities
=
normalizeEntities
(
res
?.
result
??
res
?.
data
?.
result
??
res
?.
data
??
res
);
return
{
key
:
item
.
key
,
entities
};
})
...
...
@@ -434,6 +459,7 @@ const requestAiPaneContent = async key => {
const
res
=
await
getChartAnalysis
(
{
text
:
JSON
.
stringify
(
payload
)
},
{
signal
:
getPageSignal
(),
onChunk
:
chunk
=>
{
const
current
=
overviewAiContent
.
value
[
key
];
const
base
=
current
===
"智能总结生成中..."
?
""
:
current
;
...
...
@@ -455,6 +481,7 @@ const requestAiPaneContent = async key => {
}
aiPaneFetched
.
value
=
{
...
aiPaneFetched
.
value
,
[
key
]:
true
};
}
catch
(
error
)
{
if
(
isRequestCanceled
(
error
))
return
;
console
.
error
(
"获取图表解读失败"
,
error
);
overviewAiContent
.
value
=
{
...
overviewAiContent
.
value
,
[
key
]:
"智能总结生成失败"
};
}
finally
{
...
...
@@ -518,7 +545,7 @@ const handleGetBillList = async () => {
id
:
route
.
query
.
billId
};
try
{
const
res
=
await
getBillContentId
(
params
);
const
res
=
await
getBillContentId
(
params
,
{
signal
:
getPageSignal
()
}
);
console
.
log
(
"法案id列表"
,
res
);
const
rawList
=
Array
.
isArray
(
res
?.
data
)
?
res
.
data
:
[];
const
seen
=
new
Set
();
...
...
@@ -579,7 +606,7 @@ const handleGetBillContentTk = async cRelated => {
params.content = searchKeyword.value.trim();
}
try {
const res = await getBillContentTk(params);
const res = await getBillContentTk(params
, { signal: getPageSignal() }
);
if (currentToken !== tkRequestToken.value) {
return;
}
...
...
@@ -627,6 +654,9 @@ const handleGetBillContentTk = async cRelated => {
total.value = 0;
}
} catch (error) {
if (isRequestCanceled(error)) {
return;
}
if (currentToken !== tkRequestToken.value) {
return;
}
...
...
@@ -652,7 +682,7 @@ const handleGetBillContentXzfs = async () => {
};
try {
const res = await getBillContentXzfs(params);
const res = await getBillContentXzfs(params
, { signal: getPageSignal() }
);
if (currentToken !== xzfsRequestToken.value) {
return;
}
...
...
@@ -679,6 +709,9 @@ const handleGetBillContentXzfs = async () => {
let chart1 = getPieChart(chart1Data.value, chart1ColorList.value);
setChart(chart1, "chart1");
} catch (error) {
if (isRequestCanceled(error)) {
return;
}
if (currentToken !== xzfsRequestToken.value) {
return;
}
...
...
@@ -701,7 +734,7 @@ const handleGetBillHyly = async () => {
};
try {
const res = await getBillHyly(params);
const res = await getBillHyly(params
, { signal: getPageSignal() }
);
if (currentToken !== hylyRequestToken.value) {
return;
}
...
...
@@ -729,6 +762,9 @@ const handleGetBillHyly = async () => {
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value);
setChart(chart2, "chart2");
} catch (error) {
if (isRequestCanceled(error)) {
return;
}
if (currentToken !== hylyRequestToken.value) {
return;
}
...
...
@@ -745,6 +781,14 @@ onMounted(async () => {
await handleGetBillContentXzfs();
await handleGetBillHyly();
});
onBeforeRouteLeave(() => {
stopCurrentPageRequests();
});
onBeforeUnmount(() => {
stopCurrentPageRequests();
});
</
script
>
<
style
lang=
"scss"
scoped
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论