Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
AI_BOOK_TOOL
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
template admin
AI_BOOK_TOOL
Commits
72bbd208
Commit
72bbd208
authored
Jul 30, 2025
by
liujiangnan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 暂存流式接口
parent
45e477f7
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
281 additions
and
32 deletions
+281
-32
index.css
form/index.css
+107
-0
index.html
form/index.html
+49
-0
index.js
form/index.js
+125
-32
No files found.
form/index.css
View file @
72bbd208
...
...
@@ -1166,3 +1166,110 @@ html, body {
font-size
:
12px
;
}
}
/* AI 分析遮罩层样式 */
.ai-analysis-dialog
.el-dialog
{
border-radius
:
8px
;
box-shadow
:
0
4px
20px
rgba
(
0
,
0
,
0
,
0.3
);
}
.ai-analysis-dialog
.el-dialog__header
{
background
:
linear-gradient
(
135deg
,
#667eea
0%
,
#764ba2
100%
);
color
:
white
;
border-radius
:
8px
8px
0
0
;
padding
:
15px
20px
;
}
.ai-analysis-dialog
.el-dialog__title
{
color
:
white
;
font-size
:
18px
;
font-weight
:
600
;
}
.ai-analysis-dialog
.el-dialog__body
{
padding
:
30px
20px
;
background
:
#f8f9fa
;
}
.ai-analysis-content
{
text-align
:
center
;
}
.ai-status
{
font-size
:
14px
;
font-weight
:
500
;
margin-bottom
:
20px
;
padding
:
10px
;
background
:
#e8f4fd
;
border-radius
:
4px
;
border-left
:
4px
solid
#409eff
;
}
.ai-text-area
{
margin-top
:
20px
;
}
.ai-text-area
.el-textarea__inner
{
font-family
:
'Courier New'
,
monospace
;
font-size
:
13px
;
line-height
:
1.6
;
background
:
#fafafa
;
border
:
1px
solid
#e4e7ed
;
border-radius
:
4px
;
resize
:
none
;
}
.ai-text-area
.el-textarea__inner
:focus
{
border-color
:
#409eff
;
box-shadow
:
0
0
0
2px
rgba
(
64
,
158
,
255
,
0.2
);
}
.ai-analysis-dialog
.el-dialog__footer
{
background
:
#f8f9fa
;
border-radius
:
0
0
8px
8px
;
padding
:
15px
20px
;
text-align
:
center
;
}
.ai-analysis-dialog
.dialog-footer
.el-button
{
min-width
:
100px
;
border-radius
:
20px
;
}
/* 进度条样式优化 */
.ai-analysis-content
.el-progress
{
margin-bottom
:
25px
;
}
.ai-analysis-content
.el-progress__text
{
font-size
:
14px
;
font-weight
:
600
;
color
:
#409eff
;
}
.ai-analysis-content
.el-progress-bar__outer
{
background-color
:
#e4e7ed
;
border-radius
:
10px
;
}
.ai-analysis-content
.el-progress-bar__inner
{
border-radius
:
10px
;
background
:
linear-gradient
(
90deg
,
#409eff
0%
,
#67c23a
100%
);
transition
:
all
0.3s
ease
;
}
/* 响应式设计 */
@media
(
max-width
:
768px
)
{
.ai-analysis-dialog
.el-dialog
{
width
:
90%
!important
;
margin
:
5vh
auto
;
}
.ai-analysis-dialog
.el-dialog__body
{
padding
:
20px
15px
;
}
.ai-text-area
.el-textarea__inner
{
font-size
:
12px
;
}
}
\ No newline at end of file
form/index.html
View file @
72bbd208
...
...
@@ -30,6 +30,55 @@
<body>
<div
id=
"app"
v-loading
.
fullscreen
.
lock=
"loading"
>
<el-button
style=
"position: absolute; top: 10px; right: 10px;"
@
click=
"tryAI"
>
AI重新匹配
</el-button>
<!-- AI 分析遮罩层 -->
<el-dialog
title=
"AI 分析中..."
:visible
.
sync=
"showAIAnalysis"
:close-on-click-modal=
"false"
:close-on-press-escape=
"false"
:show-close=
"false"
width=
"60%"
center
class=
"ai-analysis-dialog"
>
<div
class=
"ai-analysis-content"
>
<!-- 进度条 -->
<el-progress
:percentage=
"aiAnalysisProgress"
:status=
"aiAnalysisProgress === 100 ? 'success' : ''"
:stroke-width=
"8"
style=
"margin-bottom: 20px;"
></el-progress>
<!-- 状态信息 -->
<div
class=
"ai-status"
style=
"margin-bottom: 15px; text-align: center; color: #666;"
>
{{ aiAnalysisStatus }}
</div>
<!-- 文本显示区域 -->
<div
class=
"ai-text-area"
>
<el-input
type=
"textarea"
v-model=
"aiAnalysisText"
:rows=
"12"
readonly
placeholder=
"AI 分析结果将在这里显示..."
style=
"font-family: 'Courier New', monospace; font-size: 14px;"
></el-input>
</div>
</div>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
v-if=
"aiAnalysisProgress === 100 || aiAnalysisText.includes('失败')"
@
click=
"showAIAnalysis = false"
type=
"primary"
>
关闭
</el-button>
</span>
</el-dialog>
<!-- 文件上传界面 -->
<div
class=
"upload-container"
v-if=
"!hasData"
>
<!-- 处理进度界面 -->
...
...
form/index.js
View file @
72bbd208
...
...
@@ -11,14 +11,14 @@ const callServerMethod = (method, data) => {
});
}
//
window.courseware.getData = function (fun, key) {
//
$.getJSON('../play/defaultData_1.json', function(defaultData) {
//
console.log('加载默认数据:', defaultData);
//
fun(defaultData);
//
}).fail(function() {
//
console.error('默认数据加载失败!');
//
});
//
}
window
.
courseware
.
getData
=
function
(
fun
,
key
)
{
$
.
getJSON
(
'
../play/defaultData_1.json
'
,
function
(
defaultData
)
{
console
.
log
(
'
加载默认数据:
'
,
defaultData
);
fun
(
defaultData
);
}).
fail
(
function
()
{
console
.
error
(
'
默认数据加载失败!
'
);
});
}
new
Vue
({
...
...
@@ -107,7 +107,14 @@ new Vue({
// 新增:上传类型
uploadType
:
'
pdf
'
,
AI_SERVER_URL
:
'
https://stagingopensource.iteachabc.com
'
,
AI_SERVER_URL
:
'
http://localhost:1339
'
,
// AI_SERVER_URL: 'https://stagingopensource.iteachabc.com',
// AI 分析遮罩层相关
showAIAnalysis
:
false
,
aiAnalysisText
:
''
,
aiAnalysisStatus
:
''
,
aiAnalysisProgress
:
0
,
},
mounted
()
{
...
...
@@ -157,10 +164,10 @@ new Vue({
type
:
'
POST
'
,
contentType
:
'
application/json
'
,
data
:
JSON
.
stringify
(
data
),
success
:
function
(
response
)
{
success
:
function
(
response
)
{
resolve
(
response
);
},
error
:
function
(
xhr
,
status
,
error
)
{
error
:
function
(
xhr
,
status
,
error
)
{
reject
(
new
Error
(
error
||
'
请求失败
'
));
}
});
...
...
@@ -195,21 +202,107 @@ new Vue({
const
urlParams
=
new
URLSearchParams
(
window
.
location
.
search
);
const
coursewareId
=
urlParams
.
get
(
'
course_id
'
);
// 显示遮罩层
this
.
showAIAnalysis
=
true
;
this
.
aiAnalysisText
=
''
;
this
.
aiAnalysisStatus
=
'
正在连接服务器...
'
;
this
.
aiAnalysisProgress
=
0
;
try
{
await
this
.
postRequest
(
'
/open/api/ai/dpe/v1/pagerepair
'
,
{
courseware_id
:
coursewareId
||
1
,
page_number
:
this
.
currentPageIndex
},
{
loadingText
:
'
AI 分析中,请稍候...
'
,
successMessage
:
'
AI 分析完成
'
,
errorMessage
:
'
AI 分析失败,请稍后重试
'
this
.
aiAnalysisStatus
=
'
正在发送请求...
'
;
this
.
aiAnalysisProgress
=
20
;
const
requestUrl
=
this
.
AI_SERVER_URL
+
'
/open/api/ai/dpe/v1/pagerepair
'
;
const
requestData
=
{
courseware_id
:
coursewareId
||
1783332
,
page_number
:
this
.
currentPageIndex
};
console
.
log
(
'
请求URL:
'
,
requestUrl
);
console
.
log
(
'
请求数据:
'
,
requestData
);
// 使用 XMLHttpRequest 来处理流式响应
const
xhr
=
new
XMLHttpRequest
();
xhr
.
open
(
'
POST
'
,
requestUrl
,
true
);
xhr
.
setRequestHeader
(
'
Content-Type
'
,
'
application/json
'
);
let
lastResponseLength
=
0
;
xhr
.
onprogress
=
(
event
)
=>
{
if
(
xhr
.
readyState
===
3
||
xhr
.
readyState
===
4
)
{
const
newData
=
xhr
.
responseText
.
substring
(
lastResponseLength
);
lastResponseLength
=
xhr
.
responseText
.
length
;
if
(
newData
)
{
this
.
aiAnalysisText
+=
newData
;
this
.
aiAnalysisProgress
=
Math
.
min
(
90
,
40
+
(
this
.
aiAnalysisText
.
length
/
100
));
this
.
aiAnalysisStatus
=
`正在接收数据... (
${
this
.
aiAnalysisText
.
length
}
字符)`
;
}
}
};
xhr
.
onload
=
()
=>
{
if
(
xhr
.
status
>=
200
&&
xhr
.
status
<
300
)
{
this
.
aiAnalysisStatus
=
'
AI 分析完成,正在重新加载数据...
'
;
this
.
aiAnalysisProgress
=
95
;
// 重新加载数据
this
.
loadDefaultData
().
then
(()
=>
{
this
.
aiAnalysisStatus
=
'
AI 分析完成!
'
;
this
.
aiAnalysisProgress
=
100
;
// 2秒后自动关闭遮罩层
setTimeout
(()
=>
{
this
.
showAIAnalysis
=
false
;
},
2000
);
});
}
else
{
throw
new
Error
(
`HTTP error! status:
${
xhr
.
status
}
`
);
}
};
xhr
.
onerror
=
()
=>
{
throw
new
Error
(
'
Network error
'
);
};
xhr
.
send
(
JSON
.
stringify
(
requestData
));
// 等待 XHR 完成
await
new
Promise
((
resolve
,
reject
)
=>
{
xhr
.
onload
=
()
=>
{
if
(
xhr
.
status
>=
200
&&
xhr
.
status
<
300
)
{
resolve
();
}
else
{
reject
(
new
Error
(
`HTTP error! status:
${
xhr
.
status
}
`
));
}
};
xhr
.
onerror
=
()
=>
reject
(
new
Error
(
'
Network error
'
));
});
this
.
aiAnalysisStatus
=
'
AI 分析完成,正在重新加载数据...
'
;
this
.
aiAnalysisProgress
=
95
;
// 重新加载数据
await
this
.
loadDefaultData
();
// 显示完成消息
this
.
aiAnalysisStatus
=
'
AI 分析完成!
'
;
this
.
aiAnalysisProgress
=
100
;
// 2秒后自动关闭遮罩层
setTimeout
(()
=>
{
this
.
showAIAnalysis
=
false
;
},
2000
);
}
catch
(
error
)
{
// 错误已在 postRequest 中处理
console
.
error
(
'
AI 分析失败:
'
,
error
);
// 显示错误信息
this
.
aiAnalysisText
=
`AI 分析失败:
${
error
.
message
}
`
;
this
.
aiAnalysisStatus
=
'
分析失败,请重试
'
;
this
.
aiAnalysisProgress
=
0
;
// 5秒后自动关闭遮罩层
setTimeout
(()
=>
{
this
.
showAIAnalysis
=
false
;
},
5000
);
}
},
// 心跳实时查询异步处理进度及信息
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment