提交 552e6293 authored 作者: 张伊明's avatar 张伊明

修改写报样式

上级 944692dd
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</div> </div>
</div> </div>
<div class="sider" v-else> <div class="sider" v-else>
<div class="sider-box" v-if="false"> <div class="sider-box">
<div class="header">报文主题</div> <div class="header">报文主题</div>
<div class="title-box"> <div class="title-box">
<div class="title">主题名称</div> <div class="title">主题名称</div>
...@@ -214,7 +214,7 @@ const handleBack = () => { ...@@ -214,7 +214,7 @@ const handleBack = () => {
handleGenerate(); handleGenerate();
}; };
const isEditMode = ref(false); const isEditMode = ref(true);
const handleSwitchMode = () => { const handleSwitchMode = () => {
isEditMode.value = !isEditMode.value; isEditMode.value = !isEditMode.value;
if (!isEditMode.value) { if (!isEditMode.value) {
...@@ -283,66 +283,128 @@ const getStreamChat = async (search, inputValue) => { ...@@ -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 => { const callSseWithPdf = async selectedFile => {
// 重置中断控制器
if (abortController.value) {
abortController.value.abort();
}
abortController.value = new AbortController(); abortController.value = new AbortController();
// 状态重置
isGenerating.value = false;
isShowProcess.value = false;
try { try {
// 构造FormData(和后端字段名保持一致)
const formData = new FormData(); const formData = new FormData();
formData.append("pdf", selectedFile); formData.append("pdf", selectedFile);
// 调用fetchEventSource(核心:支持POST+FormData+SSE)
await fetchEventSource("/pdfSse/api/v1/order/pdf/extract/report/sse", { await fetchEventSource("/pdfSse/api/v1/order/pdf/extract/report/sse", {
method: "POST", // 关键:设置POST方法 method: "POST",
body: formData, // 关键:传递PDF文件的FormData body: formData,
signal: abortController.value.signal, // 中断信号 signal: abortController.value.signal,
headers: { headers: {
// 禁用默认的SSE协议头(避免和文件上传冲突)
Accept: "text/event-stream", Accept: "text/event-stream",
"Cache-Control": "no-cache", "Cache-Control": "no-cache"
Connection: "keep-alive"
}, },
openWhenHidden: true, openWhenHidden: true,
// 核心:原生onmessage回调(无需手动分割/解析) retryDelay: 1000,
async onopen(res) { maxRetries: 3,
console.log("流式回答开始", res); // 连接打开回调
async onopen(response) {
console.log("流式回答开始", response);
// 校验响应状态
if (response.ok && response.headers.get("content-type")?.includes("text/event-stream")) {
isGenerating.value = true; isGenerating.value = true;
isShowProcess.value = true; isShowProcess.value = true;
} else {
ElMessage.warning("SSE连接格式异常,即将断开");
abortController.value.abort();
}
}, },
async onmessage(res) { // 核心修复:消息处理回调
const { data, event } = res; async onmessage(event) {
const jsonData = JSON.parse(data); // 1. 严格过滤空消息(解决失焦时空消息问题)
switch (event) { 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": case "progress":
// 校验数据完整性
if (jsonData.message) {
processContent.value += `${getFormattedTime()}:${jsonData.message}\r\n`; processContent.value += `${getFormattedTime()}:${jsonData.message}\r\n`;
updateProcess(processContent.value, scrollProcessContainer.value); updateProcess(processContent.value, scrollProcessContainer.value);
}
break; break;
case "result": case "result":
callSseWithAi({ // 确保result数据有效
query: writtingTitle.value, // "输出一篇报文" if (jsonData && Object.keys(jsonData).length) {
await callSseWithAi({
query: writtingTitle.value,
desc: descText.value, desc: descText.value,
topic: "政令", topic: "政令",
result: data // 政令、智库、法案、清单 result: jsonData // 传递解析后的对象而非原始字符串
}); });
}
break;
default: default:
console.debug("未处理的SSE事件类型", event.event);
break; break;
} }
}, },
// 错误处理优化
onerror(error) { onerror(error) {
ElMessage({ console.error("SSE连接错误", error);
message: "写报生成报错!", ElMessage.warning("写报生成报错!");
type: "warning" // 只在非主动中断时重连/终止
}); if (error.name !== "AbortError") {
// 触发库的自动重连机制(返回true)
return true;
}
// 主动中断时清理控制器
abortController.value.abort(); abortController.value.abort();
abortController.value = new AbortController(); abortController.value = new AbortController();
throw new Error(error); },
// 连接关闭回调
onclose() {
console.log("SSE连接正常关闭");
isGenerating.value = false;
} }
}); });
} catch (error) { } catch (error) {
// 全局异常捕获
if (error.name !== "AbortError") { if (error.name !== "AbortError") {
ElMessage.error(`请求失败:${error.message}`); 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 => { ...@@ -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 writtingTitle = ref("");
const descText = ref(""); const descText = ref("");
const tabList = ref([ const tabList = ref([
...@@ -439,10 +491,6 @@ const tabList = ref([ ...@@ -439,10 +491,6 @@ const tabList = ref([
} }
]); ]);
const tempList = ref([ const tempList = ref([
{
title: "法案1",
desc: "基于法案内容生成各维度的综合分析报告"
},
{ {
title: "智库", title: "智库",
desc: "基于智库内容生成各维度的综合分析报告" desc: "基于智库内容生成各维度的综合分析报告"
...@@ -584,12 +632,13 @@ onUnmounted(() => { ...@@ -584,12 +632,13 @@ onUnmounted(() => {
.left-box { .left-box {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 520px; width: 525px;
padding: 21px 21px 29px 22px; padding: 21px 21px 29px 22px;
box-sizing: border-box; box-sizing: border-box;
border-right: 1px solid rgba(234, 236, 238, 1); border-right: 1px solid rgba(234, 236, 238, 1);
border-top: 1px solid rgba(234, 236, 238, 1); border-top: 1px solid rgba(234, 236, 238, 1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
overflow: scroll;
.process-box { .process-box {
display: flex; display: flex;
...@@ -1026,7 +1075,7 @@ onUnmounted(() => { ...@@ -1026,7 +1075,7 @@ onUnmounted(() => {
background: #f7f8f9; background: #f7f8f9;
.edit-panel { .edit-panel {
width: calc(100% - 100px); width: calc(100% - 170px);
height: calc(100% - 40px); height: calc(100% - 40px);
margin: 20px 50px; margin: 20px 50px;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论