Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
poc-fe
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
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
poc
poc-fe
Commits
9083858c
Commit
9083858c
authored
Dec 04, 2024
by
nick zheng
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'beta' into 'master'
fix: 语音交互优化 See merge request
!98
parents
bd14bf2f
2bd4cd34
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
425 additions
and
196 deletions
+425
-196
en.yaml
src/locales/langs/en.yaml
+8
-3
zh-cn.yaml
src/locales/langs/zh-cn.yaml
+8
-3
zh-hk.yaml
src/locales/langs/zh-hk.yaml
+8
-3
web-socket-ctr.ts
src/utils/web-socket-ctr.ts
+0
-1
agent-preview.vue
...g/components/agent-config/agent-preview/agent-preview.vue
+37
-23
footer-input.vue
...ts/agent-config/agent-preview/components/footer-input.vue
+86
-42
message-item.vue
...ts/agent-config/agent-preview/components/message-item.vue
+35
-5
message-list.vue
...ts/agent-config/agent-preview/components/message-list.vue
+5
-5
agent-role-setting.vue
...nt-config/agent-setting/components/agent-role-setting.vue
+18
-5
timbre-setting-modal.vue
...-config/agent-setting/components/timbre-setting-modal.vue
+1
-1
footer-input.vue
src/views/share/components/footer-input.vue
+83
-42
message-item.vue
src/views/share/components/message-item.vue
+50
-20
message-list.vue
src/views/share/components/message-list.vue
+5
-5
mobile-page-header.vue
src/views/share/components/mobile-page-header.vue
+1
-1
share-application-mobile.vue
src/views/share/share-application-mobile.vue
+36
-17
share-application-web.vue
src/views/share/share-application-web.vue
+36
-17
locales.d.ts
types/locales.d.ts
+8
-3
No files found.
src/locales/langs/en.yaml
View file @
9083858c
...
...
@@ -100,6 +100,8 @@ common_module:
voice_auto_play
:
'
Voice
auto
play'
start_playing
:
'
play'
stop_playing
:
'
stop'
unplayable
:
'
unplayable'
unplayable_tip
:
'
The
voice
setting
do
not
match
the
model
output
language'
response_error
:
'
Response
error'
agent_exception
:
'
Agent
exception,
please
try
again
later!'
equity
:
'
Equity'
...
...
@@ -116,6 +118,8 @@ common_module:
cancel_associate_file_tip
:
'
No
longer
answer
around
this
file'
upload_file_limit
:
'
Only
a
single
file
can
be
uploaded
in
PDF,
DOC,
DOCX,
MD,
TXT
format,
up
to
10MB'
overwrite_file_tip
:
'
The
newly
uploaded
file
overwrites
the
original
file,
whether
to
continue
uploading'
stop_playing_and_then_operate
:
'
When
the
audio
is
playing,
stop
playing
and
then
perform
the
operation'
do_not_operate_until_the_reply_is_complete
:
'
Do
not
operate
until
the
reply
is
complete'
data_table_module
:
action
:
'
Controls'
...
...
@@ -294,9 +298,10 @@ personal_space_module:
memory_fragment_delete_row_tip_content
:
'
After
data
deletion,
it
cannot
be
revoked.
Are
you
sure
you
want
to
delete
it?'
add_knowledge_successfully
:
'
Data
set
{0}
was
added
successfully'
remove_knowledge_successfully
:
'
Data
set
{0}
was
removed
successfully'
setting_timbre
:
'
Setting
timbre'
setting_timbre_message
:
'
You
can
set
the
language
and
timbre'
setting_timbre_desc
:
'
You
can
customize
the
voice
and
timbre
for
voice
broadcast,
and
you
can
set
only
one
at
a
time.'
setting_voice
:
'
Setting
voice'
setting_voice_message
:
'
You
can
set
the
language
and
tone.
If
the
selected
language
is
inconsistent
with
the
model
language,
the
speech
cannot
be
played'
setting_voice_desc
:
'
You
can
customize
the
voice
and
timbre
for
voice
broadcast,
and
you
can
set
only
one
at
a
time.'
currently_only_one_voice_can_be_set
:
'
Currently,
you
can
set
only
one
voice'
memory_variable_modal
:
edit_memory_variable
:
'
Edit
memory
variable'
...
...
src/locales/langs/zh-cn.yaml
View file @
9083858c
...
...
@@ -99,6 +99,8 @@ common_module:
voice_auto_play
:
'
语音自动播放'
start_playing
:
'
开始播放'
stop_playing
:
'
停止播放'
unplayable
:
'
不可播放'
unplayable_tip
:
'
语音设置与模型输出语言不匹配'
response_error
:
'
响应错误'
agent_exception
:
'
应用异常,请稍后重试!'
equity
:
'
权益'
...
...
@@ -115,6 +117,8 @@ common_module:
cancel_associate_file_tip
:
'
不再围绕这个文件回答'
upload_file_limit
:
'
仅支持上传单个文件,支持PDF、DOC、DOCX、MD、TXT格式,最大10MB'
overwrite_file_tip
:
'
新上传的文件会覆盖原有文件,是否继续上传'
stop_playing_and_then_operate
:
'
音频播放中,请停止播放后再操作'
do_not_operate_until_the_reply_is_complete
:
'
回复完成后再操作'
data_table_module
:
action
:
'
操作'
...
...
@@ -292,9 +296,10 @@ personal_space_module:
memory_fragment_delete_row_tip_content
:
'
数据删除后不可撤销,确定要删除吗?'
add_knowledge_successfully
:
'
数据集
{0}
添加成功'
remove_knowledge_successfully
:
'
数据集
{0}
移除成功'
setting_timbre
:
'
设置音色'
setting_timbre_message
:
'
你可以设置语言和音色'
setting_timbre_desc
:
'
您可自定义语音及音色,用于语音播报,且每次仅可设置一种。'
setting_voice
:
'
设置语音'
setting_voice_message
:
'
你可以设置语言和音色,若所选语言与模型语言不一致,则无法播放语音'
setting_voice_desc
:
'
您可自定义语音及音色,用于语音播报,且每次仅可设置一种。'
currently_only_one_voice_can_be_set
:
'
当前仅可设置一种声音'
memory_variable_modal
:
edit_memory_variable
:
'
编辑记忆变量'
...
...
src/locales/langs/zh-hk.yaml
View file @
9083858c
...
...
@@ -99,6 +99,8 @@ common_module:
voice_auto_play
:
'
語音自動播放'
start_playing
:
'
開始播放'
stop_playing
:
'
停止播放'
unplayable
:
'
不可播放'
unplayable_tip
:
'
語音設置與模型輸出語言不匹配'
response_error
:
'
響應錯誤'
agent_exception
:
'
應用異常,請稍後重試!'
equity
:
'
权益'
...
...
@@ -115,6 +117,8 @@ common_module:
cancel_associate_file_tip
:
'
不再圍繞這個文件回答'
upload_file_limit
:
'
僅支持上傳單個文件,支持PDF、DOC、DOCX、MD、TXT格式,最大10MB'
overwrite_file_tip
:
'
新上傳的文件會覆蓋原有文件,是否繼續上傳'
stop_playing_and_then_operate
:
'
音頻播放中,請停止播放後再操作'
do_not_operate_until_the_reply_is_complete
:
'
回覆完成後再操作'
data_table_module
:
action
:
'
操作'
...
...
@@ -292,9 +296,10 @@ personal_space_module:
memory_fragment_delete_row_tip_content
:
'
數據删除後不可撤銷,確定要删除嗎?'
add_knowledge_successfully
:
'
數據集
{0}
添加成功'
remove_knowledge_successfully
:
'
數據集
{0}
移除成功'
setting_timbre
:
'
設置音色'
setting_timbre_message
:
'
你可以設置語言和音色'
setting_timbre_desc
:
'
您可自定義語音及音色,用於語音播報,且每次僅可設置一種。'
setting_voice
:
'
設置語音'
setting_voice_message
:
'
你可以設置語言和音色,若所選語言與模型語言不一致,則無法播放語音'
setting_voice_desc
:
'
您可自定義語音及音色,用於語音播報,且每次僅可設置一種。'
currently_only_one_voice_can_be_set
:
'
當前僅可設置一種聲音'
memory_variable_modal
:
edit_memory_variable
:
'
編輯記憶變數'
...
...
src/utils/web-socket-ctr.ts
View file @
9083858c
...
...
@@ -39,7 +39,6 @@ export default class WebSocketCtr {
this
.
socket
.
close
()
this
.
socket
=
null
}
window
.
$message
.
error
(
t
(
'common_module.agent_exception'
))
this
.
onMessageError
()
...
...
src/views/personal-space/personal-app-setting/components/agent-config/agent-preview/agent-preview.vue
View file @
9083858c
...
...
@@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n'
import
{
useRouter
}
from
'vue-router'
import
{
Emitter
}
from
'mitt'
import
{
Howl
}
from
'howler'
import
{
ValueOf
}
from
'type-fest'
import
MessageList
from
'./components/message-list.vue'
import
FooterInput
from
'./components/footer-input.vue'
import
MemoryPreviewModal
from
'./components/memory-preview-modal.vue'
...
...
@@ -26,15 +27,15 @@ const emitter = inject<Emitter<MittEvents>>('emitter')
const
messageListRef
=
ref
<
InstanceType
<
typeof
MessageList
>
|
null
>
(
null
)
const
footerInputRef
=
ref
<
InstanceType
<
typeof
FooterInput
>
|
null
>
(
null
)
const
messageList
=
ref
<
ConversationMessageItem
[]
>
([]
)
const
messageList
=
ref
(
new
Map
<
string
,
ConversationMessageItem
>
()
)
const
continuousQuestionStatus
=
ref
<
'default'
|
'close'
>
(
personalAppConfigStore
.
commConfig
.
continuousQuestionStatus
)
const
continuousQuestionList
=
ref
<
string
[]
>
([])
const
isShowMemoryPreviewModal
=
ref
(
false
)
const
selectedMemoryTabName
=
ref
(
'memoryVariable'
)
const
answerAudioAutoPlay
ing
=
ref
(
personalAppConfigStore
.
voiceConfig
.
defaultOpen
===
'Y'
)
const
answerAudioAutoPlay
=
ref
(
personalAppConfigStore
.
voiceConfig
.
defaultOpen
===
'Y'
)
const
answerAudioPlaying
=
ref
(
false
)
// 语音播放中
const
currentPlayMessageItem
=
ref
<
ConversationMessageItem
|
null
>
(
null
)
const
currentPlayAudioFragmentSerialNo
=
ref
(
0
)
const
currentSoundCtl
=
shallowRef
<
Howl
|
null
>
(
null
)
...
...
@@ -48,7 +49,7 @@ onMounted(() => {
emitter
?.
on
(
'resetAgent'
,
()
=>
{
handleAudioPause
()
footerInputRef
.
value
?.
blockMessageResponse
()
messageList
.
value
=
[]
messageList
.
value
.
clear
()
})
})
...
...
@@ -56,23 +57,34 @@ onUnmounted(() => {
emitter
?.
off
(
'resetAgent'
)
handleAudioPause
()
footerInputRef
.
value
?.
blockMessageResponse
()
messageList
.
value
=
[]
messageList
.
value
.
clear
()
})
function
handleAddMessageItem
(
messageItem
:
ConversationMessageItem
)
{
messageList
.
value
.
push
(
messageItem
)
function
handleAddMessageItem
(
messageI
d
:
string
,
messageI
tem
:
ConversationMessageItem
)
{
messageList
.
value
.
set
(
messageId
,
messageItem
)
}
function
handleUpdateSpecifyMessageItem
(
messageItemIndex
:
number
,
newObj
:
Partial
<
ConversationMessageItem
>
)
{
if
(
messageList
.
value
[
messageItemIndex
])
{
Object
.
entries
(
newObj
).
forEach
(([
k
,
v
])
=>
{
;(
messageList
.
value
[
messageItemIndex
]
as
any
)[
k
as
keyof
typeof
newObj
]
=
v
function
handleUpdateSpecifyMessageItem
(
messageId
:
string
,
newMessageItem
:
Partial
<
ConversationMessageItem
>
)
{
const
currentMessageItemInfo
=
messageList
.
value
.
get
(
messageId
)
if
(
currentMessageItemInfo
)
{
const
updatePropertyLength
=
Object
.
keys
(
newMessageItem
).
length
if
(
updatePropertyLength
>
4
)
{
messageList
.
value
.
set
(
messageId
,
Object
.
assign
({},
currentMessageItemInfo
,
newMessageItem
))
return
}
Object
.
entries
<
ValueOf
<
typeof
newMessageItem
>>
(
newMessageItem
).
forEach
(([
key
,
value
])
=>
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
currentMessageItemInfo
,
key
))
{
;(
currentMessageItemInfo
as
any
)[
key
as
keyof
ConversationMessageItem
]
=
value
}
})
}
}
function
handleDeleteLastMessageItem
()
{
messageList
.
value
.
pop
(
)
function
handleDeleteLastMessageItem
(
messageId
:
string
)
{
messageList
.
value
.
delete
(
messageId
)
}
function
handleUpdatePageScroll
()
{
...
...
@@ -88,7 +100,8 @@ function handleClearAllMessage() {
.
then
(()
=>
{
handleAudioPause
()
footerInputRef
.
value
?.
blockMessageResponse
()
messageList
.
value
=
[]
messageList
.
value
.
clear
()
answerAudioPlaying
.
value
=
false
window
.
$message
.
success
(
t
(
'common_module.clear_success_message'
))
})
}
...
...
@@ -135,6 +148,7 @@ function howlSoundFactory(url: string) {
preload
:
true
,
autoplay
:
true
,
onplay
:
()
=>
{
answerAudioPlaying
.
value
=
true
currentSoundCtl
.
value
=
soundCtl
if
(
currentPlayMessageItem
.
value
)
{
...
...
@@ -152,6 +166,7 @@ function howlSoundFactory(url: string) {
currentPlayAudioFragmentSerialNo
.
value
>
currentPlayMessageItem
.
value
.
voiceFragmentUrlList
.
length
-
1
)
{
currentPlayMessageItem
.
value
.
isVoicePlaying
=
false
answerAudioPlaying
.
value
=
false
}
let
audioFragmentUrl
=
currentPlayMessageItem
.
value
?.
voiceFragmentUrlList
[
currentPlayAudioFragmentSerialNo
.
value
]
...
...
@@ -205,9 +220,10 @@ function handleAudioPause(isClearMessageList = false) {
}
currentPlayMessageItem
.
value
&&
(
currentPlayMessageItem
.
value
.
isVoicePlaying
=
false
)
answerAudioPlaying
.
value
=
false
if
(
isClearMessageList
)
{
messageList
.
value
=
[]
messageList
.
value
.
clear
()
footerInputRef
.
value
?.
blockMessageResponse
()
}
}
...
...
@@ -231,11 +247,7 @@ function handleAudioPause(isClearMessageList = false) {
</
template
>
<div
class=
"flex items-center gap-2.5"
>
<span>
{{ t('common_module.voice_auto_play') }}
</span>
<n-switch
v-model:value=
"answerAudioAutoPlaying"
size=
"small"
@
update:value=
"handleUpdateAudioAutoPlaying"
>
<n-switch
v-model:value=
"answerAudioAutoPlay"
size=
"small"
@
update:value=
"handleUpdateAudioAutoPlaying"
>
<
template
#
checked
>
{{
t
(
'common_module.open'
)
}}
</
template
>
<
template
#
unchecked
>
{{
t
(
'common_module.close'
)
}}
</
template
>
</n-switch>
...
...
@@ -294,11 +306,11 @@ function handleAudioPause(isClearMessageList = false) {
</div>
<div
class=
"flex w-full flex-1 overflow-hidden"
>
<div
v-show=
"messageList.
length
=== 0"
class=
"flex w-full"
>
<div
v-show=
"messageList.
size
=== 0"
class=
"flex w-full"
>
<Preamble
/>
</div>
<div
v-show=
"messageList.
length
> 0"
class=
"w-full"
>
<div
v-show=
"messageList.
size
> 0"
class=
"w-full"
>
<MessageList
ref=
"messageListRef"
:message-list=
"messageList"
...
...
@@ -314,7 +326,8 @@ function handleAudioPause(isClearMessageList = false) {
ref=
"footerInputRef"
:continuous-question-status=
"continuousQuestionStatus"
:message-list=
"messageList"
:answer-audio-auto-playing=
"answerAudioAutoPlaying"
:answer-audio-auto-play=
"answerAudioAutoPlay"
:answer-audio-playing=
"answerAudioPlaying"
@
add-message-item=
"handleAddMessageItem"
@
update-specify-message-item=
"handleUpdateSpecifyMessageItem"
@
delete-last-message-item=
"handleDeleteLastMessageItem"
...
...
@@ -323,6 +336,7 @@ function handleAudioPause(isClearMessageList = false) {
@
create-continue-questions=
"handleCreateContinueQuestions"
@
update-continuous-question-status=
"handleUpdateContinueQuestionStatus"
@
audio-play=
"handleAudioPlay"
@
audio-pause=
"handleAudioPause"
/>
<MemoryPreviewModal
v-model=
"isShowMemoryPreviewModal"
:data=
"selectedMemoryTabName"
/>
...
...
src/views/personal-space/personal-app-setting/components/agent-config/agent-preview/components/footer-input.vue
View file @
9083858c
This diff is collapsed.
Click to expand it.
src/views/personal-space/personal-app-setting/components/agent-config/agent-preview/components/message-item.vue
View file @
9083858c
...
...
@@ -31,13 +31,27 @@ const assistantAvatar = computed(() => {
return
personalAppConfigStore
.
baseInfo
.
agentAvatar
})
const
timbreEnabled
=
computed
(()
=>
{
return
!!
personalAppConfigStore
.
voiceConfig
.
timbreId
})
const
isShowAudioControl
=
computed
(()
=>
{
return
(
props
.
role
===
'assistant'
&&
!
props
.
messageItem
.
isVoiceLoading
&&
!!
props
.
messageItem
.
voiceFragmentUrlList
.
length
)
return
props
.
role
===
'assistant'
&&
!
props
.
messageItem
.
isVoiceLoading
})
const
isPlayableAudio
=
computed
(()
=>
{
return
isShowAudioControl
.
value
&&
!!
props
.
messageItem
.
voiceFragmentUrlList
.
length
})
const
isShowVoiceLoading
=
computed
(()
=>
{
return
props
.
role
===
'assistant'
&&
props
.
messageItem
.
isVoiceLoading
&&
timbreEnabled
.
value
})
function
handleAudioControl
()
{
if
(
!
isPlayableAudio
.
value
)
{
return
}
if
(
props
.
messageItem
.
isVoicePlaying
)
{
emit
(
'audioPause'
)
}
else
{
...
...
@@ -86,14 +100,30 @@ function handleAudioControl() {
<div
v-show=
"isShowAudioControl"
class=
"hover:text-theme-color text-font-color flex cursor-pointer items-center gap-0.5 hover:opacity-80"
class=
"text-font-color flex items-center gap-0.5"
:class=
"isPlayableAudio ? 'hover:text-theme-color cursor-pointer hover:opacity-80' : 'cursor-not-allowed'"
@
click=
"handleAudioControl"
>
<i
v-if=
"!messageItem.isVoicePlaying"
class=
"iconfont icon-play text-[24px]"
/>
<div
v-else
class=
"mx-1.5 my-3 h-[12px] w-[12px] bg-[url(@/assets/images/playing.gif)] bg-[length:100%_100%]"
/>
<span
class=
"text-[12px]"
:class=
"messageItem.isVoicePlaying ? 'text-theme-color' : ''"
>
<span
v-show=
"isPlayableAudio"
class=
"text-[12px]"
:class=
"messageItem.isVoicePlaying ? 'text-theme-color' : ''"
>
{{
messageItem
.
isVoicePlaying
?
t
(
'common_module.stop_playing'
)
:
t
(
'common_module.start_playing'
)
}}
</span>
<n-popover
style=
"max-width: 310px"
>
<template
#
trigger
>
<span
v-show=
"!isPlayableAudio"
class=
"text-[12px]"
>
{{
t
(
'common_module.unplayable'
)
}}
</span>
</
template
>
{{ t('common_module.unplayable_tip') }}
</n-popover>
</div>
<div
v-if=
"isShowVoiceLoading"
class=
"py-3.5 pl-6"
>
<CustomLoading
/>
</div>
</div>
</div>
...
...
src/views/personal-space/personal-app-setting/components/agent-config/agent-preview/components/message-list.vue
View file @
9083858c
...
...
@@ -5,7 +5,7 @@ import ContinueQuestion from './continue-question.vue'
import
{
useScroll
}
from
'@/composables/useScroll'
interface
Props
{
messageList
:
ConversationMessageItem
[]
messageList
:
Map
<
string
,
ConversationMessageItem
>
continuousQuestionStatus
:
'default'
|
'close'
continuousQuestionList
:
string
[]
}
...
...
@@ -22,8 +22,8 @@ const { scrollRef, scrollToBottom } = useScroll()
const
isShowContinueQuestion
=
computed
(()
=>
{
return
(
props
.
continuousQuestionStatus
===
'default'
&&
props
.
messageList
.
length
>
1
&&
!
props
.
messageList
[
props
.
messageList
.
length
-
1
].
isAnswerResponseLoading
props
.
messageList
.
size
>
1
&&
!
Array
.
from
(
props
.
messageList
.
entries
()).
pop
()?.[
1
].
isAnswerResponseLoading
)
})
...
...
@@ -36,8 +36,8 @@ defineExpose({
<main
ref=
"scrollRef"
class=
"h-full overflow-y-auto px-5"
>
<div>
<MessageItem
v-for=
"
messageItem
in messageList"
:key=
"
messageItem.timestamp
"
v-for=
"
[key, messageItem]
in messageList"
:key=
"
key
"
:role=
"messageItem.role"
:message-item=
"messageItem"
@
audio-play=
"() => $emit('audioPlay', messageItem)"
...
...
src/views/personal-space/personal-app-setting/components/agent-config/agent-setting/components/agent-role-setting.vue
View file @
9083858c
...
...
@@ -31,6 +31,8 @@ const timberFullName = computed(() => {
return
`
${
timbreInfoDetail
.
value
?.
timbreInfo
?.[
0
]?.
timbreName
||
'--'
}(
$
{
t
(
currentLanguage
?.
label
||
'common_module.sound'
)})
`
})
const isHasTimbreId = computed(() => !!voiceConfig.value.timbreId)
onMounted(() => {
voiceConfig.value.timbreId && handleGetTimberInfoDetail()
})
...
...
@@ -49,6 +51,10 @@ function handleUpdateRoleConfigExpandedNames(expandedNames: string[]) {
}
function handleShowAssociatedTimbreModel() {
if (voiceConfig.value.timbreId) {
return
}
isShowTimbreSettingModal.value = true
timbreInfo = { language: 0, matchLang: '', timbreInfo: [] }
}
...
...
@@ -84,7 +90,7 @@ function handleEditAssociatedTimbreModel() {
<RightOne
theme=
"filled"
size=
"17"
fill=
"#333"
:stroke-width=
"3"
/>
</
template
>
<NCollapseItem
:title=
"t('common_module.
sound
')"
name=
"timbre"
class=
"my-[13px]!"
>
<NCollapseItem
:title=
"t('common_module.
voice
')"
name=
"timbre"
class=
"my-[13px]!"
>
<
template
#
header-extra
>
<NTooltip
trigger=
"hover"
>
<template
#
trigger
>
...
...
@@ -92,16 +98,23 @@ function handleEditAssociatedTimbreModel() {
theme=
"outline"
size=
"22"
:stroke-width=
"3"
class=
"text-theme-color cursor-pointer"
class=
"text-theme-color"
:class=
"isHasTimbreId ? 'cursor-not-allowed' : 'cursor-pointer'"
@
click=
"handleShowAssociatedTimbreModel"
/>
</
template
>
{{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.setting_timbre') }}
{{
isHasTimbreId
? t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.currently_only_one_voice_can_be_set',
)
: t('personal_space_module.agent_module.agent_setting_module.agent_config_module.setting_voice')
}}
</NTooltip>
</template>
<span
v-show=
"!voiceConfig.timbreId"
class=
"text-xs text-[#84868c]"
>
{{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.setting_
timbr
e_desc') }}
{{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.setting_
voic
e_desc') }}
</span>
<div
class=
"flex flex-1 flex-wrap items-center gap-[12px] overflow-hidden"
>
...
...
@@ -153,7 +166,7 @@ function handleEditAssociatedTimbreModel() {
<TimbreSettingModal
v-model:is-show-modal=
"isShowTimbreSettingModal"
:btn-loading=
"false"
:modal-title=
"t('personal_space_module.agent_module.agent_setting_module.agent_config_module.setting_
timbr
e')"
:modal-title=
"t('personal_space_module.agent_module.agent_setting_module.agent_config_module.setting_
voic
e')"
:timbre-info=
"timbreInfo"
@
confirm=
"handleUpdateTimbreId"
/>
...
...
src/views/personal-space/personal-app-setting/components/agent-config/agent-setting/components/timbre-setting-modal.vue
View file @
9083858c
...
...
@@ -215,7 +215,7 @@ function handleAudioPause() {
>
<template
#
content
>
<div
class=
"text-gray-font-color mb-2"
>
{{
t
(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.setting_
timbr
e_message'
)
}}
{{
t
(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.setting_
voic
e_message'
)
}}
</div>
<div
v-show=
"!requestDataLoading"
class=
"flex items-center gap-3"
>
...
...
src/views/share/components/footer-input.vue
View file @
9083858c
This diff is collapsed.
Click to expand it.
src/views/share/components/message-item.vue
View file @
9083858c
...
...
@@ -38,25 +38,27 @@ const assistantAvatar = computed(() => {
)
})
const
isShowWebAudioControl
=
computed
(()
=>
{
return
(
props
.
role
===
'assistant'
&&
!
props
.
messageItem
.
isVoiceLoading
&&
!
isMobile
.
value
&&
!!
props
.
messageItem
.
voiceFragmentUrlList
.
length
)
const
timbreEnabled
=
computed
(()
=>
{
return
!!
props
.
agentApplicationConfig
.
voiceConfig
.
timbreId
})
const
isShowMobileAudioControl
=
computed
(()
=>
{
return
(
props
.
role
===
'assistant'
&&
!
props
.
messageItem
.
isVoiceLoading
&&
isMobile
.
value
&&
!!
props
.
messageItem
.
voiceFragmentUrlList
.
length
)
const
isShowAudioControl
=
computed
(()
=>
{
return
props
.
role
===
'assistant'
&&
!
props
.
messageItem
.
isVoiceLoading
&&
timbreEnabled
.
value
})
const
isPlayableAudio
=
computed
(()
=>
{
return
isShowAudioControl
.
value
&&
!!
props
.
messageItem
.
voiceFragmentUrlList
.
length
})
const
isShowWebVoiceLoading
=
computed
(()
=>
{
return
props
.
role
===
'assistant'
&&
!
isMobile
.
value
&&
props
.
messageItem
.
isVoiceLoading
&&
timbreEnabled
.
value
})
function
handleAudioControl
()
{
if
(
!
isPlayableAudio
.
value
)
{
return
}
if
(
props
.
messageItem
.
isVoicePlaying
)
{
emit
(
'audioPause'
)
}
else
{
...
...
@@ -107,32 +109,60 @@ function handleAudioControl() {
/>
</p>
<div
v-show=
"role === 'assistant' && messageItem.isAnswerResponseLoading"
class=
"mb-[5px] mt-4 px-4"
>
<div
v-show=
"
role === 'assistant' && (messageItem.isAnswerResponseLoading || (isMobile && messageItem.isVoiceLoading))
"
class=
"mb-[5px] mt-4 px-4"
>
<CustomLoading
/>
</div>
</div>
<div
v-show=
"isShow
MobileAudioControl
"
class=
"mt-[13px] flex items-center gap-2"
>
<div
v-show=
"isShow
AudioControl && isMobile
"
class=
"mt-[13px] flex items-center gap-2"
>
<div
class=
"h-[18px] w-[18px] cursor-pointer"
:class=
"messageItem.isVoicePlaying ? 'bg-svg-pause' : 'bg-svg-play'"
@
click=
"handleAudioControl"
/>
<MusicWavesLoading
v-show=
"messageItem.isVoicePlaying"
bar-bg-color=
"#333"
/>
<MusicWavesLoading
v-show=
"messageItem.isVoicePlaying && isPlayableAudio"
bar-bg-color=
"#333"
/>
<n-popover
style=
"max-width: 310px"
>
<template
#
trigger
>
<span
v-show=
"!isPlayableAudio"
class=
"text-[12px]"
>
{{
t
(
'common_module.unplayable'
)
}}
</span>
</
template
>
{{ t('common_module.unplayable_tip') }}
</n-popover>
</div>
</div>
<div
v-show=
"isShowWebAudioControl"
class=
"hover:text-theme-color text-font-color flex cursor-pointer items-center gap-0.5 hover:opacity-80"
v-show=
"isShowAudioControl && !isMobile"
class=
"text-font-color flex items-center gap-0.5"
:class=
"isPlayableAudio ? 'hover:text-theme-color cursor-pointer hover:opacity-80' : 'cursor-not-allowed'"
@
click=
"handleAudioControl"
>
<i
v-if=
"!messageItem.isVoicePlaying"
class=
"iconfont icon-play text-[24px]"
/>
<div
v-else
class=
"mx-1.5 my-3 h-[12px] w-[12px] bg-[url(@/assets/images/playing.gif)] bg-[length:100%_100%]"
/>
<span
class=
"text-[12px]"
:class=
"messageItem.isVoicePlaying ? 'text-theme-color' : ''"
>
<span
v-show=
"isPlayableAudio"
class=
"text-[12px]"
:class=
"messageItem.isVoicePlaying ? 'text-theme-color' : ''"
>
{{ messageItem.isVoicePlaying ? t('common_module.stop_playing') : t('common_module.start_playing') }}
</span>
<n-popover
style=
"max-width: 310px"
>
<
template
#
trigger
>
<span
v-show=
"!isPlayableAudio"
class=
"text-[12px]"
>
{{
t
(
'common_module.unplayable'
)
}}
</span>
</
template
>
{{ t('common_module.unplayable_tip') }}
</n-popover>
</div>
<div
v-if=
"isShowWebVoiceLoading"
class=
"py-3.5 pl-5"
>
<CustomLoading
/>
</div>
</div>
</div>
...
...
src/views/share/components/message-list.vue
View file @
9083858c
...
...
@@ -6,7 +6,7 @@ import { PersonalAppConfigState } from '@/store/types/personal-app-config'
import
{
computed
}
from
'vue'
interface
Props
{
messageList
:
ConversationMessageItem
[]
messageList
:
Map
<
string
,
ConversationMessageItem
>
agentApplicationConfig
:
PersonalAppConfigState
continuousQuestionStatus
:
'default'
|
'close'
continuousQuestionList
:
string
[]
...
...
@@ -24,8 +24,8 @@ const { scrollRef, scrollToBottom } = useScroll()
const
isShowContinueQuestion
=
computed
(()
=>
{
return
(
props
.
continuousQuestionStatus
===
'default'
&&
props
.
messageList
.
length
>
1
&&
!
props
.
messageList
[
props
.
messageList
.
length
-
1
].
isAnswerResponseLoading
props
.
messageList
.
size
>
1
&&
!
Array
.
from
(
props
.
messageList
.
entries
()).
pop
()?.[
1
].
isAnswerResponseLoading
)
})
...
...
@@ -38,8 +38,8 @@ defineExpose({
<main
ref=
"scrollRef"
class=
"h-full overflow-y-auto px-5"
>
<div>
<MessageItem
v-for=
"
messageItem
in messageList"
:key=
"
messageItem.timestamp
"
v-for=
"
[key, messageItem]
in messageList"
:key=
"
key
"
:role=
"messageItem.role"
:message-item=
"messageItem"
:agent-application-config=
"agentApplicationConfig"
...
...
src/views/share/components/mobile-page-header.vue
View file @
9083858c
...
...
@@ -38,7 +38,7 @@ function handleToLogin() {
<NButton
v-show=
"isLogin"
type=
"primary"
class=
"rounded-md! h-[32px]! text-xs! w-[80px]!"
class=
"rounded-md! h-[32px]! text-xs!
min-
w-[80px]!"
@
click=
"handleToCreateApplication"
>
{{
t
(
'common_module.create_agent_btn_text'
)
}}
...
...
src/views/share/share-application-mobile.vue
View file @
9083858c
...
...
@@ -3,6 +3,7 @@ import { computed, onMounted, onUnmounted, ref, shallowRef } from 'vue'
import
{
useRouter
}
from
'vue-router'
import
{
useI18n
}
from
'vue-i18n'
import
{
Howl
}
from
'howler'
import
{
ValueOf
}
from
'type-fest'
import
PageHeader
from
'./components/mobile-page-header.vue'
import
Preamble
from
'./components/preamble.vue'
import
MessageList
from
'./components/message-list.vue'
...
...
@@ -37,11 +38,12 @@ const agentApplicationConfig = ref<PersonalAppConfigState>(defaultPersonalAppCon
const
messageListRef
=
ref
<
InstanceType
<
typeof
MessageList
>
|
null
>
(
null
)
const
footerInputRef
=
ref
<
InstanceType
<
typeof
FooterInput
>
|
null
>
(
null
)
const
messageList
=
ref
<
ConversationMessageItem
[]
>
([]
)
const
messageList
=
ref
(
new
Map
<
string
,
ConversationMessageItem
>
()
)
const
continuousQuestionStatus
=
ref
<
'default'
|
'close'
>
(
'default'
)
const
continueQuestionList
=
ref
<
string
[]
>
([])
const
answerAudioAutoPlaying
=
ref
(
false
)
const
answerAudioAutoPlay
=
ref
(
false
)
// 语音是否自动播放
const
answerAudioPlaying
=
ref
(
false
)
// 语音播放中
const
currentPlayMessageItem
=
ref
<
ConversationMessageItem
|
null
>
(
null
)
const
currentPlayAudioFragmentSerialNo
=
ref
(
0
)
const
currentSoundCtl
=
shallowRef
<
Howl
|
null
>
(
null
)
...
...
@@ -110,7 +112,7 @@ async function handleGetAutoPlayByAgentId() {
const
res
=
await
fetchGetAutoPlayByAgentId
<
'Y'
|
'N'
>
(
agentId
.
value
)
if
(
res
.
code
===
0
)
{
answerAudioAutoPlay
ing
.
value
=
res
.
data
===
'Y'
answerAudioAutoPlay
.
value
=
res
.
data
===
'Y'
}
}
...
...
@@ -134,20 +136,31 @@ async function handleUpdateAutoPlaying(isAutoPlaying: boolean) {
await
fetchUpdateAutoPlay
(
agentId
.
value
,
autoplay
)
}
function
handleAddMessageItem
(
messageItem
:
ConversationMessageItem
)
{
messageList
.
value
.
push
(
messageItem
)
function
handleAddMessageItem
(
messageI
d
:
string
,
messageI
tem
:
ConversationMessageItem
)
{
messageList
.
value
.
set
(
messageId
,
messageItem
)
}
function
handleUpdateSpecifyMessageItem
(
messageItemIndex
:
number
,
newObj
:
Partial
<
ConversationMessageItem
>
)
{
if
(
messageList
.
value
[
messageItemIndex
])
{
Object
.
entries
(
newObj
).
forEach
(([
k
,
v
])
=>
{
;(
messageList
.
value
[
messageItemIndex
]
as
any
)[
k
as
keyof
typeof
newObj
]
=
v
function
handleUpdateSpecifyMessageItem
(
messageId
:
string
,
newMessageItem
:
Partial
<
ConversationMessageItem
>
)
{
const
currentMessageItemInfo
=
messageList
.
value
.
get
(
messageId
)
if
(
currentMessageItemInfo
)
{
const
updatePropertyLength
=
Object
.
keys
(
newMessageItem
).
length
if
(
updatePropertyLength
>
4
)
{
messageList
.
value
.
set
(
messageId
,
Object
.
assign
({},
currentMessageItemInfo
,
newMessageItem
))
return
}
Object
.
entries
<
ValueOf
<
typeof
newMessageItem
>>
(
newMessageItem
).
forEach
(([
key
,
value
])
=>
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
currentMessageItemInfo
,
key
))
{
;(
currentMessageItemInfo
as
any
)[
key
as
keyof
ConversationMessageItem
]
=
value
}
})
}
}
function
handleDeleteLastMessageItem
()
{
messageList
.
value
.
pop
(
)
function
handleDeleteLastMessageItem
(
messageId
:
string
)
{
messageList
.
value
.
delete
(
messageId
)
}
function
handleUpdatePageScroll
()
{
...
...
@@ -163,7 +176,8 @@ function handleClearAllMessage() {
.
then
(()
=>
{
handleAudioPause
()
footerInputRef
.
value
?.
blockMessageResponse
()
messageList
.
value
=
[]
messageList
.
value
.
clear
()
answerAudioPlaying
.
value
=
false
window
.
$message
.
success
(
t
(
'common_module.clear_success_message'
))
})
}
...
...
@@ -189,6 +203,7 @@ function howlSoundFactory(url: string) {
preload
:
true
,
autoplay
:
true
,
onplay
:
()
=>
{
answerAudioPlaying
.
value
=
true
currentSoundCtl
.
value
=
soundCtl
if
(
currentPlayMessageItem
.
value
)
{
...
...
@@ -206,6 +221,7 @@ function howlSoundFactory(url: string) {
currentPlayAudioFragmentSerialNo
.
value
>
currentPlayMessageItem
.
value
.
voiceFragmentUrlList
.
length
-
1
)
{
currentPlayMessageItem
.
value
.
isVoicePlaying
=
false
answerAudioPlaying
.
value
=
false
}
let
audioFragmentUrl
=
currentPlayMessageItem
.
value
?.
voiceFragmentUrlList
[
currentPlayAudioFragmentSerialNo
.
value
]
...
...
@@ -259,9 +275,10 @@ function handleAudioPause(isClearMessageList = false) {
}
currentPlayMessageItem
.
value
&&
(
currentPlayMessageItem
.
value
.
isVoicePlaying
=
false
)
answerAudioPlaying
.
value
=
false
if
(
isClearMessageList
)
{
messageList
.
value
=
[]
messageList
.
value
.
clear
()
footerInputRef
.
value
?.
blockMessageResponse
()
}
}
...
...
@@ -279,18 +296,18 @@ function handleAudioPause(isClearMessageList = false) {
<div
class=
"mt-5 flex select-none justify-end px-4"
>
<div
v-show=
"isEnableVoice"
class=
"flex items-center gap-2"
>
<span>
{{
t
(
'common_module.voice_auto_play'
)
}}
</span>
<n-switch
v-model:value=
"answerAudioAutoPlay
ing
"
size=
"small"
@
update:value=
"handleUpdateAutoPlaying"
>
<n-switch
v-model:value=
"answerAudioAutoPlay"
size=
"small"
@
update:value=
"handleUpdateAutoPlaying"
>
<template
#
checked
>
{{
t
(
'common_module.open'
)
}}
</
template
>
<
template
#
unchecked
>
{{
t
(
'common_module.close'
)
}}
</
template
>
</n-switch>
</div>
</div>
<div
v-if=
"messageList.
length
=== 0"
class=
"w-full flex-1 overflow-auto px-4"
>
<div
v-if=
"messageList.
size
=== 0"
class=
"w-full flex-1 overflow-auto px-4"
>
<Preamble
:agent-application-config=
"agentApplicationConfig"
/>
</div>
<div
v-if=
"messageList.
length
> 0"
class=
"flex w-full flex-1 flex-col overflow-hidden pt-5"
>
<div
v-if=
"messageList.
size
> 0"
class=
"flex w-full flex-1 flex-col overflow-hidden pt-5"
>
<div
class=
"flex-1 overflow-auto"
>
<MessageList
ref=
"messageListRef"
...
...
@@ -313,7 +330,8 @@ function handleAudioPause(isClearMessageList = false) {
:continuous-question-status=
"continuousQuestionStatus"
:is-enable-document-parse=
"isEnableDocumentParse"
:is-enable-voice=
"isEnableVoice"
:answer-audio-auto-playing=
"answerAudioAutoPlaying"
:answer-audio-auto-play=
"answerAudioAutoPlay"
:answer-audio-playing=
"answerAudioPlaying"
:timbre-id=
"agentApplicationConfig.voiceConfig.timbreId"
@
add-message-item=
"handleAddMessageItem"
@
update-specify-message-item=
"handleUpdateSpecifyMessageItem"
...
...
@@ -324,6 +342,7 @@ function handleAudioPause(isClearMessageList = false) {
@
create-continue-questions=
"handleCreateContinueQuestions"
@
reset-continue-question-list=
"handleResetContinueQuestionList"
@
audio-play=
"handleAudioPlay"
@
audio-pause=
"handleAudioPause"
/>
</div>
</div>
...
...
src/views/share/share-application-web.vue
View file @
9083858c
...
...
@@ -3,6 +3,7 @@ import { computed, onMounted, onUnmounted, ref, shallowRef } from 'vue'
import
{
useRouter
}
from
'vue-router'
import
{
useI18n
}
from
'vue-i18n'
import
{
Howl
}
from
'howler'
import
{
ValueOf
}
from
'type-fest'
import
PageHeader
from
'./components/web-page-header.vue'
import
Preamble
from
'./components/preamble.vue'
import
MessageList
from
'./components/message-list.vue'
...
...
@@ -40,11 +41,12 @@ const agentApplicationConfig = ref<PersonalAppConfigState>(defaultPersonalAppCon
const
messageListRef
=
ref
<
InstanceType
<
typeof
MessageList
>
|
null
>
(
null
)
const
footerInputRef
=
ref
<
InstanceType
<
typeof
FooterInput
>
|
null
>
(
null
)
const
messageList
=
ref
<
ConversationMessageItem
[]
>
([]
)
const
messageList
=
ref
(
new
Map
<
string
,
ConversationMessageItem
>
()
)
const
continuousQuestionStatus
=
ref
<
'default'
|
'close'
>
(
'default'
)
const
continueQuestionList
=
ref
<
string
[]
>
([])
const
answerAudioAutoPlaying
=
ref
(
false
)
const
answerAudioAutoPlay
=
ref
(
false
)
const
answerAudioPlaying
=
ref
(
false
)
// 语音播放中
const
currentPlayMessageItem
=
ref
<
ConversationMessageItem
|
null
>
(
null
)
const
currentPlayAudioFragmentSerialNo
=
ref
(
0
)
const
currentSoundCtl
=
shallowRef
<
Howl
|
null
>
(
null
)
...
...
@@ -123,7 +125,7 @@ async function handleGetAutoPlayByAgentId() {
const
res
=
await
fetchGetAutoPlayByAgentId
<
'Y'
|
'N'
>
(
agentId
.
value
)
if
(
res
.
code
===
0
)
{
answerAudioAutoPlay
ing
.
value
=
res
.
data
===
'Y'
answerAudioAutoPlay
.
value
=
res
.
data
===
'Y'
}
}
...
...
@@ -155,20 +157,31 @@ async function handleUpdateAutoPlaying(isAutoPlaying: boolean) {
await
fetchUpdateAutoPlay
(
agentId
.
value
,
autoplay
)
}
function
handleAddMessageItem
(
messageItem
:
ConversationMessageItem
)
{
messageList
.
value
.
push
(
messageItem
)
function
handleAddMessageItem
(
messageI
d
:
string
,
messageI
tem
:
ConversationMessageItem
)
{
messageList
.
value
.
set
(
messageId
,
messageItem
)
}
function
handleUpdateSpecifyMessageItem
(
messageItemIndex
:
number
,
newObj
:
Partial
<
ConversationMessageItem
>
)
{
if
(
messageList
.
value
[
messageItemIndex
])
{
Object
.
entries
(
newObj
).
forEach
(([
k
,
v
])
=>
{
;(
messageList
.
value
[
messageItemIndex
]
as
any
)[
k
as
keyof
typeof
newObj
]
=
v
function
handleUpdateSpecifyMessageItem
(
messageId
:
string
,
newMessageItem
:
Partial
<
ConversationMessageItem
>
)
{
const
currentMessageItemInfo
=
messageList
.
value
.
get
(
messageId
)
if
(
currentMessageItemInfo
)
{
const
updatePropertyLength
=
Object
.
keys
(
newMessageItem
).
length
if
(
updatePropertyLength
>
4
)
{
messageList
.
value
.
set
(
messageId
,
Object
.
assign
({},
currentMessageItemInfo
,
newMessageItem
))
return
}
Object
.
entries
<
ValueOf
<
typeof
newMessageItem
>>
(
newMessageItem
).
forEach
(([
key
,
value
])
=>
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
currentMessageItemInfo
,
key
))
{
;(
currentMessageItemInfo
as
any
)[
key
as
keyof
ConversationMessageItem
]
=
value
}
})
}
}
function
handleDeleteLastMessageItem
()
{
messageList
.
value
.
pop
(
)
function
handleDeleteLastMessageItem
(
messageId
:
string
)
{
messageList
.
value
.
delete
(
messageId
)
}
function
handleUpdatePageScroll
()
{
...
...
@@ -184,7 +197,8 @@ function handleClearAllMessage() {
.
then
(()
=>
{
handleAudioPause
()
footerInputRef
.
value
?.
blockMessageResponse
()
messageList
.
value
=
[]
messageList
.
value
.
clear
()
answerAudioPlaying
.
value
=
false
window
.
$message
.
success
(
t
(
'common_module.clear_success_message'
))
})
}
...
...
@@ -210,6 +224,7 @@ function howlSoundFactory(url: string) {
preload
:
true
,
autoplay
:
true
,
onplay
:
()
=>
{
answerAudioPlaying
.
value
=
true
currentSoundCtl
.
value
=
soundCtl
if
(
currentPlayMessageItem
.
value
)
{
...
...
@@ -227,6 +242,7 @@ function howlSoundFactory(url: string) {
currentPlayAudioFragmentSerialNo
.
value
>
currentPlayMessageItem
.
value
.
voiceFragmentUrlList
.
length
-
1
)
{
currentPlayMessageItem
.
value
.
isVoicePlaying
=
false
answerAudioPlaying
.
value
=
false
}
let
audioFragmentUrl
=
currentPlayMessageItem
.
value
?.
voiceFragmentUrlList
[
currentPlayAudioFragmentSerialNo
.
value
]
...
...
@@ -280,9 +296,10 @@ function handleAudioPause(isClearMessageList = false) {
}
currentPlayMessageItem
.
value
&&
(
currentPlayMessageItem
.
value
.
isVoicePlaying
=
false
)
answerAudioPlaying
.
value
=
false
if
(
isClearMessageList
)
{
messageList
.
value
=
[]
messageList
.
value
.
clear
()
footerInputRef
.
value
?.
blockMessageResponse
()
}
}
...
...
@@ -303,17 +320,17 @@ function handleAudioPause(isClearMessageList = false) {
<div
class=
"relative mx-auto flex h-full w-[1000px] flex-col overflow-hidden"
>
<div
v-show=
"isEnableVoice"
class=
"absolute right-10 top-7 flex select-none items-center gap-2"
>
<span>
{{
t
(
'common_module.voice_auto_play'
)
}}
</span>
<n-switch
v-model:value=
"answerAudioAutoPlay
ing
"
size=
"small"
@
update:value=
"handleUpdateAutoPlaying"
>
<n-switch
v-model:value=
"answerAudioAutoPlay"
size=
"small"
@
update:value=
"handleUpdateAutoPlaying"
>
<template
#
checked
>
{{
t
(
'common_module.open'
)
}}
</
template
>
<
template
#
unchecked
>
{{
t
(
'common_module.close'
)
}}
</
template
>
</n-switch>
</div>
<div
v-if=
"messageList.
length
=== 0"
class=
"w-full flex-1 overflow-auto px-5"
>
<div
v-if=
"messageList.
size
=== 0"
class=
"w-full flex-1 overflow-auto px-5"
>
<Preamble
:agent-application-config=
"agentApplicationConfig"
/>
</div>
<div
v-if=
"messageList.
length
> 0"
class=
"flex w-full flex-1 flex-col overflow-hidden"
>
<div
v-if=
"messageList.
size
> 0"
class=
"flex w-full flex-1 flex-col overflow-hidden"
>
<div
class=
"mt-20 flex-1 overflow-auto"
>
<MessageList
ref=
"messageListRef"
...
...
@@ -336,7 +353,8 @@ function handleAudioPause(isClearMessageList = false) {
:continuous-question-status=
"continuousQuestionStatus"
:is-enable-document-parse=
"isEnableDocumentParse"
:is-enable-voice=
"isEnableVoice"
:answer-audio-auto-playing=
"answerAudioAutoPlaying"
:answer-audio-auto-play=
"answerAudioAutoPlay"
:answer-audio-playing=
"answerAudioPlaying"
:timbre-id=
"agentApplicationConfig.voiceConfig.timbreId"
@
add-message-item=
"handleAddMessageItem"
@
update-specify-message-item=
"handleUpdateSpecifyMessageItem"
...
...
@@ -347,6 +365,7 @@ function handleAudioPause(isClearMessageList = false) {
@
create-continue-questions=
"handleCreateContinueQuestions"
@
reset-continue-question-list=
"handleResetContinueQuestionList"
@
audio-play=
"handleAudioPlay"
@
audio-pause=
"handleAudioPause"
/>
</div>
</div>
...
...
types/locales.d.ts
View file @
9083858c
...
...
@@ -100,6 +100,8 @@ declare namespace I18n {
voice_auto_play
:
string
start_playing
:
string
stop_playing
:
string
unplayable
:
string
unplayable_tip
:
string
response_error
:
string
agent_exception
:
string
equity
:
string
...
...
@@ -116,6 +118,8 @@ declare namespace I18n {
cancel_associate_file_tip
:
string
upload_file_limit
:
string
overwrite_file_tip
:
string
stop_playing_and_then_operate
:
string
do_not_operate_until_the_reply_is_complete
:
string
}
data_table_module
:
{
...
...
@@ -292,9 +296,10 @@ declare namespace I18n {
memory_fragment_delete_row_tip_content
:
string
add_knowledge_successfully
:
string
remove_knowledge_successfully
:
string
setting_timbre
:
string
setting_timbre_message
:
string
setting_timbre_desc
:
string
setting_voice
:
string
setting_voice_message
:
string
setting_voice_desc
:
string
currently_only_one_voice_can_be_set
:
string
memory_variable_modal
:
{
edit_memory_variable
:
string
...
...
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