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
ad5cf1dd
Commit
ad5cf1dd
authored
Jul 30, 2025
by
liujiangnan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat
parent
72bbd208
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
92 additions
and
139 deletions
+92
-139
index.html
form/index.html
+5
-3
index.js
form/index.js
+87
-136
No files found.
form/index.html
View file @
ad5cf1dd
...
...
@@ -31,7 +31,7 @@
<div
id=
"app"
v-loading
.
fullscreen
.
lock=
"loading"
>
<el-button
style=
"position: absolute; top: 10px; right: 10px;"
@
click=
"tryAI"
>
AI重新匹配
</el-button>
<!-- AI 分析遮罩层 -->
<!-- AI 分析遮罩层
-->
<el-dialog
title=
"AI 分析中..."
:visible
.
sync=
"showAIAnalysis"
...
...
@@ -59,19 +59,21 @@
<!-- 文本显示区域 -->
<div
class=
"ai-text-area"
>
<el-input
ref=
"aiTextArea"
type=
"textarea"
v-model=
"aiAnalysisText"
:rows=
"
12
"
:rows=
"
24
"
readonly
placeholder=
"AI 分析结果将在这里显示..."
style=
"font-family: 'Courier New', monospace; font-size: 14px;"
@
scroll=
"handleTextAreaScroll"
></el-input>
</div>
</div>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
v-if=
"aiAnalysisProgress === 100 || aiAnalysisText.includes('失败')"
:disabled=
"aiAnalysisProgress < 100 && !aiAnalysisText.includes('失败')"
@
click=
"showAIAnalysis = false"
type=
"primary"
>
...
...
form/index.js
View file @
ad5cf1dd
...
...
@@ -115,6 +115,9 @@ new Vue({
aiAnalysisText
:
''
,
aiAnalysisStatus
:
''
,
aiAnalysisProgress
:
0
,
// 滚动控制相关
shouldAutoScroll
:
true
,
userScrolled
:
false
,
},
mounted
()
{
...
...
@@ -134,70 +137,6 @@ new Vue({
methods
:
{
// 公共的 POST 请求方法
async
postRequest
(
endpoint
,
data
,
options
=
{})
{
const
{
loadingText
=
'
请求中,请稍候...
'
,
successMessage
=
'
请求成功
'
,
errorMessage
=
'
请求失败
'
,
showLoading
=
true
,
showSuccessMessage
=
true
,
showErrorMessage
=
true
}
=
options
;
let
loading
=
null
;
if
(
showLoading
)
{
loading
=
this
.
$loading
({
lock
:
true
,
text
:
loadingText
,
spinner
:
'
el-icon-loading
'
,
background
:
'
rgba(0, 0, 0, 0.7)
'
});
}
try
{
const
result
=
await
new
Promise
((
resolve
,
reject
)
=>
{
$
.
ajax
({
url
:
this
.
AI_SERVER_URL
+
endpoint
,
type
:
'
POST
'
,
contentType
:
'
application/json
'
,
data
:
JSON
.
stringify
(
data
),
success
:
function
(
response
)
{
resolve
(
response
);
},
error
:
function
(
xhr
,
status
,
error
)
{
reject
(
new
Error
(
error
||
'
请求失败
'
));
}
});
});
if
(
result
.
code
===
200
)
{
if
(
showSuccessMessage
)
{
this
.
$message
.
success
(
successMessage
);
}
return
result
;
}
else
{
const
errorMsg
=
result
.
message
||
errorMessage
;
if
(
showErrorMessage
)
{
this
.
$message
.
error
(
errorMsg
);
}
throw
new
Error
(
errorMsg
);
}
}
catch
(
error
)
{
console
.
error
(
'
请求失败:
'
,
error
);
if
(
showErrorMessage
)
{
this
.
$message
.
error
(
error
.
message
||
errorMessage
);
}
throw
error
;
}
finally
{
if
(
loading
)
{
loading
.
close
();
}
}
},
async
tryAI
()
{
const
urlParams
=
new
URLSearchParams
(
window
.
location
.
search
);
const
coursewareId
=
urlParams
.
get
(
'
course_id
'
);
...
...
@@ -207,6 +146,10 @@ new Vue({
this
.
aiAnalysisText
=
''
;
this
.
aiAnalysisStatus
=
'
正在连接服务器...
'
;
this
.
aiAnalysisProgress
=
0
;
// 重置滚动状态
this
.
shouldAutoScroll
=
true
;
this
.
userScrolled
=
false
;
try
{
this
.
aiAnalysisStatus
=
'
正在发送请求...
'
;
...
...
@@ -215,96 +158,104 @@ new Vue({
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
);
await
new
Promise
((
resolve
,
reject
)
=>
{
// 使用 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
;
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
;
// 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
)
=>
{
if
(
newData
)
{
this
.
aiAnalysisText
+=
newData
;
this
.
aiAnalysisProgress
=
Math
.
min
(
90
,
Math
.
floor
(
40
+
(
this
.
aiAnalysisText
.
length
/
100
)));
this
.
aiAnalysisStatus
=
`正在接收数据... (
${
this
.
aiAnalysisText
.
length
}
字符)`
;
// 自动滚动到底部
this
.
scrollAITextToBottom
();
}
}
};
xhr
.
onload
=
()
=>
{
if
(
xhr
.
status
>=
200
&&
xhr
.
status
<
300
)
{
resolve
();
this
.
aiAnalysisStatus
=
'
AI 分析完成,正在重新加载数据...
'
;
this
.
aiAnalysisProgress
=
95
;
// 重新加载数据
this
.
loadDefaultData
().
then
(()
=>
{
this
.
aiAnalysisStatus
=
'
AI 分析完成!
'
;
this
.
aiAnalysisProgress
=
100
;
resolve
();
});
}
else
{
reject
(
new
Error
(
`HTTP error! status:
${
xhr
.
status
}
`
));
}
};
xhr
.
onerror
=
()
=>
reject
(
new
Error
(
'
Network error
'
));
xhr
.
onerror
=
()
=>
{
reject
(
new
Error
(
'
Network error
'
));
};
xhr
.
send
(
JSON
.
stringify
(
requestData
));
});
this
.
aiAnalysisStatus
=
'
AI 分析完成,正在重新加载数据...
'
;
this
.
aiAnalysisProgress
=
95
;
// 重新加载数据
await
this
.
loadDefaultData
();
// 显示完成消息
this
.
aiAnalysisStatus
=
'
AI 分析完成!
'
;
this
.
aiAnalysisProgress
=
100
;
// 2秒后自动关闭遮罩层
setTimeout
(()
=>
{
this
.
showAIAnalysis
=
false
;
},
2000
);
}
catch
(
error
)
{
console
.
error
(
'
AI 分析失败:
'
,
error
);
// 显示错误信息
this
.
aiAnalysisText
=
`AI 分析失败:
${
error
.
message
}
`
;
this
.
aiAnalysisStatus
=
'
分析失败,请重试
'
;
this
.
aiAnalysisProgress
=
0
;
// 5秒后自动关闭遮罩层
this
.
aiAnalysisProgress
=
0
;
}
},
// 处理文本区域滚动
handleTextAreaScroll
(
event
)
{
const
textarea
=
event
.
target
;
const
isAtBottom
=
textarea
.
scrollTop
+
textarea
.
clientHeight
>=
textarea
.
scrollHeight
-
5
;
// 如果用户手动滚动到底部,恢复自动滚动
if
(
isAtBottom
)
{
this
.
userScrolled
=
false
;
this
.
shouldAutoScroll
=
true
;
}
else
{
// 如果用户向上滚动,暂停自动滚动
this
.
userScrolled
=
true
;
this
.
shouldAutoScroll
=
false
;
}
},
// 滚动AI文本区域到底部
scrollAITextToBottom
()
{
console
.
log
(
'
尝试滚动到底部,shouldAutoScroll:
'
,
this
.
shouldAutoScroll
);
if
(
this
.
$refs
.
aiTextArea
&&
this
.
shouldAutoScroll
)
{
// 使用setTimeout确保DOM完全更新
setTimeout
(()
=>
{
this
.
showAIAnalysis
=
false
;
},
5000
);
// 尝试多种方式获取textarea元素
let
textarea
=
this
.
$refs
.
aiTextArea
.
$el
.
querySelector
(
'
textarea
'
);
if
(
!
textarea
)
{
textarea
=
this
.
$refs
.
aiTextArea
.
$el
.
querySelector
(
'
.el-textarea__inner
'
);
}
if
(
!
textarea
)
{
textarea
=
this
.
$refs
.
aiTextArea
.
$el
.
querySelector
(
'
textarea, .el-textarea__inner
'
);
}
console
.
log
(
'
找到textarea:
'
,
!!
textarea
);
if
(
textarea
)
{
console
.
log
(
'
设置scrollTop:
'
,
textarea
.
scrollHeight
);
textarea
.
scrollTop
=
textarea
.
scrollHeight
;
}
else
{
console
.
log
(
'
未找到textarea元素
'
);
}
},
10
);
}
},
// 心跳实时查询异步处理进度及信息
async
checkProcess
(
_data
)
{
let
data
=
_data
;
...
...
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