Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
552e6293
提交
552e6293
authored
1月 27, 2026
作者:
张伊明
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
修改写报样式
上级
944692dd
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
98 行增加
和
49 行删除
+98
-49
index.vue
src/views/writtingAsstaint/index.vue
+98
-49
没有找到文件。
src/views/writtingAsstaint/index.vue
浏览文件 @
552e6293
...
...
@@ -50,7 +50,7 @@
</div>
</div>
<div
class=
"sider"
v-else
>
<div
class=
"sider-box"
v-if=
"false"
>
<div
class=
"sider-box"
>
<div
class=
"header"
>
报文主题
</div>
<div
class=
"title-box"
>
<div
class=
"title"
>
主题名称
</div>
...
...
@@ -214,7 +214,7 @@ const handleBack = () => {
handleGenerate
();
};
const
isEditMode
=
ref
(
fals
e
);
const
isEditMode
=
ref
(
tru
e
);
const
handleSwitchMode
=
()
=>
{
isEditMode
.
value
=
!
isEditMode
.
value
;
if
(
!
isEditMode
.
value
)
{
...
...
@@ -283,66 +283,128 @@ const getStreamChat = async (search, inputValue) => {
}
};
const
getFormattedTime
=
()
=>
{
const
now
=
new
Date
();
// 补零函数:确保单个数字补为两位(如 1 → 01,9 → 09)
const
pad
=
n
=>
n
.
toString
().
padStart
(
2
,
"0"
);
return
`
${
now
.
getFullYear
()}
-
${
pad
(
now
.
getMonth
()
+
1
)}
-
${
pad
(
now
.
getDate
())}
${
pad
(
now
.
getHours
())}
:
${
pad
(
now
.
getMinutes
()
)}
:
${
pad
(
now
.
getSeconds
())}
`
;
};
// 核心SSE调用函数(修复后)
const
callSseWithPdf
=
async
selectedFile
=>
{
// 重置中断控制器
if
(
abortController
.
value
)
{
abortController
.
value
.
abort
();
}
abortController
.
value
=
new
AbortController
();
// 状态重置
isGenerating
.
value
=
false
;
isShowProcess
.
value
=
false
;
try
{
// 构造FormData(和后端字段名保持一致)
const
formData
=
new
FormData
();
formData
.
append
(
"pdf"
,
selectedFile
);
// 调用fetchEventSource(核心:支持POST+FormData+SSE)
await
fetchEventSource
(
"/pdfSse/api/v1/order/pdf/extract/report/sse"
,
{
method
:
"POST"
,
// 关键:设置POST方法
body
:
formData
,
// 关键:传递PDF文件的FormData
signal
:
abortController
.
value
.
signal
,
// 中断信号
method
:
"POST"
,
body
:
formData
,
signal
:
abortController
.
value
.
signal
,
headers
:
{
// 禁用默认的SSE协议头(避免和文件上传冲突)
Accept
:
"text/event-stream"
,
"Cache-Control"
:
"no-cache"
,
Connection
:
"keep-alive"
"Cache-Control"
:
"no-cache"
},
openWhenHidden
:
true
,
// 核心:原生onmessage回调(无需手动分割/解析)
async
onopen
(
res
)
{
console
.
log
(
"流式回答开始"
,
res
);
isGenerating
.
value
=
true
;
isShowProcess
.
value
=
true
;
retryDelay
:
1000
,
maxRetries
:
3
,
// 连接打开回调
async
onopen
(
response
)
{
console
.
log
(
"流式回答开始"
,
response
);
// 校验响应状态
if
(
response
.
ok
&&
response
.
headers
.
get
(
"content-type"
)?.
includes
(
"text/event-stream"
))
{
isGenerating
.
value
=
true
;
isShowProcess
.
value
=
true
;
}
else
{
ElMessage
.
warning
(
"SSE连接格式异常,即将断开"
);
abortController
.
value
.
abort
();
}
},
async
onmessage
(
res
)
{
const
{
data
,
event
}
=
res
;
const
jsonData
=
JSON
.
parse
(
data
);
switch
(
event
)
{
// 核心修复:消息处理回调
async
onmessage
(
event
)
{
// 1. 严格过滤空消息(解决失焦时空消息问题)
if
(
!
event
||
!
event
.
data
||
event
.
data
.
trim
()
===
""
)
{
console
.
debug
(
"收到空SSE消息,忽略"
,
event
);
return
;
}
let
jsonData
=
null
;
try
{
// 2. 容错处理:防止非JSON格式的消息导致解析报错
jsonData
=
JSON
.
parse
(
event
.
data
.
trim
());
}
catch
(
parseError
)
{
console
.
warn
(
"SSE消息JSON解析失败"
,
parseError
,
event
.
data
);
return
;
}
// 3. 按事件类型处理业务逻辑
switch
(
event
.
event
)
{
case
"progress"
:
processContent
.
value
+=
`
${
getFormattedTime
()}
:
${
jsonData
.
message
}
\r\n`
;
updateProcess
(
processContent
.
value
,
scrollProcessContainer
.
value
);
// 校验数据完整性
if
(
jsonData
.
message
)
{
processContent
.
value
+=
`
${
getFormattedTime
()}
:
${
jsonData
.
message
}
\r\n`
;
updateProcess
(
processContent
.
value
,
scrollProcessContainer
.
value
);
}
break
;
case
"result"
:
callSseWithAi
({
query
:
writtingTitle
.
value
,
// "输出一篇报文"
desc
:
descText
.
value
,
topic
:
"政令"
,
result
:
data
// 政令、智库、法案、清单
});
// 确保result数据有效
if
(
jsonData
&&
Object
.
keys
(
jsonData
).
length
)
{
await
callSseWithAi
({
query
:
writtingTitle
.
value
,
desc
:
descText
.
value
,
topic
:
"政令"
,
result
:
jsonData
// 传递解析后的对象而非原始字符串
});
}
break
;
default
:
console
.
debug
(
"未处理的SSE事件类型"
,
event
.
event
);
break
;
}
},
// 错误处理优化
onerror
(
error
)
{
ElMessage
({
message
:
"写报生成报错!"
,
type
:
"warning"
});
console
.
error
(
"SSE连接错误"
,
error
);
ElMessage
.
warning
(
"写报生成报错!"
);
// 只在非主动中断时重连/终止
if
(
error
.
name
!==
"AbortError"
)
{
// 触发库的自动重连机制(返回true)
return
true
;
}
// 主动中断时清理控制器
abortController
.
value
.
abort
();
abortController
.
value
=
new
AbortController
();
throw
new
Error
(
error
);
},
// 连接关闭回调
onclose
()
{
console
.
log
(
"SSE连接正常关闭"
);
isGenerating
.
value
=
false
;
}
});
}
catch
(
error
)
{
// 全局异常捕获
if
(
error
.
name
!==
"AbortError"
)
{
ElMessage
.
error
(
`请求失败:
${
error
.
message
}
`
);
isLoading
.
value
=
false
;
console
.
error
(
"SSE请求异常"
,
error
)
;
}
// 重置状态
isGenerating
.
value
=
false
;
isShowProcess
.
value
=
false
;
// 清理控制器
abortController
.
value
.
abort
();
abortController
.
value
=
new
AbortController
();
}
};
...
...
@@ -412,16 +474,6 @@ const callSseWithAi = async params => {
});
};
const
getFormattedTime
=
()
=>
{
const
now
=
new
Date
();
// 补零函数:确保单个数字补为两位(如 1 → 01,9 → 09)
const
pad
=
n
=>
n
.
toString
().
padStart
(
2
,
"0"
);
return
`
${
now
.
getFullYear
()}
-
${
pad
(
now
.
getMonth
()
+
1
)}
-
${
pad
(
now
.
getDate
())}
${
pad
(
now
.
getHours
())}
:
${
pad
(
now
.
getMinutes
()
)}
:
${
pad
(
now
.
getSeconds
())}
`
;
};
const
writtingTitle
=
ref
(
""
);
const
descText
=
ref
(
""
);
const
tabList
=
ref
([
...
...
@@ -439,10 +491,6 @@ const tabList = ref([
}
]);
const
tempList
=
ref
([
{
title
:
"法案1"
,
desc
:
"基于法案内容生成各维度的综合分析报告"
},
{
title
:
"智库"
,
desc
:
"基于智库内容生成各维度的综合分析报告"
...
...
@@ -584,12 +632,13 @@ onUnmounted(() => {
.left-box
{
display
:
flex
;
flex-direction
:
column
;
width
:
52
0
px
;
width
:
52
5
px
;
padding
:
21px
21px
29px
22px
;
box-sizing
:
border-box
;
border-right
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-top
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
overflow
:
scroll
;
.process-box
{
display
:
flex
;
...
...
@@ -1026,7 +1075,7 @@ onUnmounted(() => {
background
:
#f7f8f9
;
.edit-panel
{
width
:
calc
(
100%
-
1
0
0px
);
width
:
calc
(
100%
-
1
7
0px
);
height
:
calc
(
100%
-
40px
);
margin
:
20px
50px
;
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论