Commit d3082bd4 authored by nick zheng's avatar nick zheng

Merge branch 'beta' into 'master'

Beta

See merge request !193
parents 78d27728 a564e5ad
...@@ -166,6 +166,8 @@ common_module: ...@@ -166,6 +166,8 @@ common_module:
overwrite_image_tip: 'The newly uploaded image overwrites the original image, whether to continue uploading' overwrite_image_tip: 'The newly uploaded image overwrites the original image, whether to continue uploading'
upload_image_size_error_message: 'The size of the uploaded image cannot exceed 5 MB' upload_image_size_error_message: 'The size of the uploaded image cannot exceed 5 MB'
upload_image_format_error_message: 'Only png, jpg, jpeg, webp format images can be uploaded, please upload again' upload_image_format_error_message: 'Only png, jpg, jpeg, webp format images can be uploaded, please upload again'
do_not_exit_page: 'Do not leave the page during the generation to avoid interrupting the conversation'
content_interrupted: 'Content generation is interrupted. Whether to regenerate it'
data_table_module: data_table_module:
action: 'Controls' action: 'Controls'
......
...@@ -165,6 +165,8 @@ common_module: ...@@ -165,6 +165,8 @@ common_module:
overwrite_image_tip: '新上传的图片会覆盖原有图片,是否继续上传' overwrite_image_tip: '新上传的图片会覆盖原有图片,是否继续上传'
upload_image_size_error_message: '上传图片大小不能超过5M' upload_image_size_error_message: '上传图片大小不能超过5M'
upload_image_format_error_message: '只能上传png、jpg、jpeg、webp格式图片,请重新上传' upload_image_format_error_message: '只能上传png、jpg、jpeg、webp格式图片,请重新上传'
do_not_exit_page: '生成期间请勿离开页面,以免中断对话流程'
content_interrupted: '内容生成被中断,是否重新生成'
data_table_module: data_table_module:
action: '操作' action: '操作'
......
...@@ -165,6 +165,8 @@ common_module: ...@@ -165,6 +165,8 @@ common_module:
overwrite_image_tip: '新上傳的圖片會覆蓋原有圖片,是否繼續上傳' overwrite_image_tip: '新上傳的圖片會覆蓋原有圖片,是否繼續上傳'
upload_image_size_error_message: '上傳圖片大小不能超過5M' upload_image_size_error_message: '上傳圖片大小不能超過5M'
upload_image_format_error_message: '只能上傳png、jpg、jpeg、webp格式圖片,請重新上傳' upload_image_format_error_message: '只能上傳png、jpg、jpeg、webp格式圖片,請重新上傳'
do_not_exit_page: '生成期間請勿離開頁面,以免中斷對話流程'
content_interrupted: '內容生成被中斷,是否重新生成'
data_table_module: data_table_module:
action: '操作' action: '操作'
......
...@@ -54,12 +54,11 @@ const userStore = useUserStore() ...@@ -54,12 +54,11 @@ const userStore = useUserStore()
const { uploadFileList, handleLimitUpload, handleUpload, handleRemoveFile } = useDialogueFile() const { uploadFileList, handleLimitUpload, handleUpload, handleRemoveFile } = useDialogueFile()
const { uploadImageList, handleLimitUploadImage, handleUploadImage, handleRemoveUploadImage } = useUploadImage() const { uploadImageList, handleLimitUploadImage, handleUploadImage, handleRemoveUploadImage } = useUploadImage()
const isAnswerResponseLoading = defineModel<boolean>('isAnswerResponseLoading', { required: true }) const isAnswerResponseWait = defineModel<boolean>('isAnswerResponseLoading', { required: true })
const emitter = inject<Emitter<MittEvents>>('emitter') const emitter = inject<Emitter<MittEvents>>('emitter')
const inputMessageContent = ref('') const inputMessageContent = ref('')
const isAnswerResponseWait = ref(false)
const currentReplyContentSentenceExtractIndex = ref(0) const currentReplyContentSentenceExtractIndex = ref(0)
const sentenceFragmentSerialNo = ref(0) const sentenceFragmentSerialNo = ref(0)
const sentenceExtractCheckEnabled = ref(false) const sentenceExtractCheckEnabled = ref(false)
...@@ -154,12 +153,16 @@ function handleInputMessageEnter(event: KeyboardEvent) { ...@@ -154,12 +153,16 @@ function handleInputMessageEnter(event: KeyboardEvent) {
} }
} }
function handleMessageSend() { function handleMessageSend(lastQuestionContent?: string) {
if (!isLogin.value) { if (!isLogin.value) {
window.$message.warning(t('common_module.not_login_text')) window.$message.warning(t('common_module.not_login_text'))
return return
} }
if (lastQuestionContent) {
inputMessageContent.value = lastQuestionContent
}
if (!inputMessageContent.value.trim() || isInputMessageDisabled.value) { if (!inputMessageContent.value.trim() || isInputMessageDisabled.value) {
return return
} }
...@@ -198,7 +201,6 @@ function handleMessageSend() { ...@@ -198,7 +201,6 @@ function handleMessageSend() {
let replyTextContent = '' let replyTextContent = ''
let reasoningContent = '' let reasoningContent = ''
isAnswerResponseLoading.value = true
isAnswerResponseWait.value = true isAnswerResponseWait.value = true
currentReplyContentSentenceExtractIndex.value = 0 currentReplyContentSentenceExtractIndex.value = 0
sentenceFragmentSerialNo.value = 0 sentenceFragmentSerialNo.value = 0
...@@ -272,7 +274,6 @@ function handleMessageSend() { ...@@ -272,7 +274,6 @@ function handleMessageSend() {
isAnswerResponseLoading: false, isAnswerResponseLoading: false,
}) })
isAnswerResponseLoading.value = false
isCreateContinueQuestions.value && emit('createContinueQuestions', replyTextContent) isCreateContinueQuestions.value && emit('createContinueQuestions', replyTextContent)
emit('updatePageScroll') emit('updatePageScroll')
isAnswerResponseWait.value = false isAnswerResponseWait.value = false
...@@ -440,6 +441,8 @@ function ttsSocketSendText(text: string, audioUrlSerialNo: number, messageId: st ...@@ -440,6 +441,8 @@ function ttsSocketSendText(text: string, audioUrlSerialNo: number, messageId: st
defineExpose({ defineExpose({
blockMessageResponse, blockMessageResponse,
errorMessageResponse,
handleMessageSend,
}) })
</script> </script>
...@@ -544,7 +547,7 @@ defineExpose({ ...@@ -544,7 +547,7 @@ defineExpose({
? 'opacity-60' ? 'opacity-60'
: 'cursor-pointer' : 'cursor-pointer'
" "
@click="handleMessageSend" @click="handleMessageSend()"
/> />
<div v-show="!isLogin" class="absolute left-3 top-[5px] flex h-[30px] items-center text-[#84868c]"> <div v-show="!isLogin" class="absolute left-3 top-[5px] flex h-[30px] items-center text-[#84868c]">
......
<script setup lang="ts"> <script setup lang="ts">
import { computed, nextTick, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import MessageItem from './message-item.vue' import MessageItem from './message-item.vue'
import ContinueQuestion from './continue-question.vue' import ContinueQuestion from './continue-question.vue'
import { useScroll } from '@/composables/useScroll' import { useScroll } from '@/composables/useScroll'
import { PersonalAppConfigState } from '@/store/types/personal-app-config' import { PersonalAppConfigState } from '@/store/types/personal-app-config'
import { computed, nextTick, watch } from 'vue'
import { useBackBottom } from '@/composables/useBackBottom' import { useBackBottom } from '@/composables/useBackBottom'
import { useLayoutConfig } from '@/composables/useLayoutConfig'
interface Props { interface Props {
messageList: Map<string, ConversationMessageItem> messageList: Map<string, ConversationMessageItem>
...@@ -13,6 +15,7 @@ interface Props { ...@@ -13,6 +15,7 @@ interface Props {
continuousQuestionList: string[] continuousQuestionList: string[]
isAnswerResponseLoading: boolean isAnswerResponseLoading: boolean
createContinueQuestionsException: boolean createContinueQuestionsException: boolean
lastQuestionContent?: string
} }
const props = defineProps<Props>() const props = defineProps<Props>()
...@@ -22,6 +25,10 @@ defineEmits<{ ...@@ -22,6 +25,10 @@ defineEmits<{
audioPause: [] audioPause: []
}>() }>()
const { t } = useI18n()
const { isMobile } = useLayoutConfig()
const { scrollRef, scrollToBottom } = useScroll() const { scrollRef, scrollToBottom } = useScroll()
const { visible, clickBackBottom, throttleScrollContainer } = useBackBottom(scrollRef, scrollToBottom) const { visible, clickBackBottom, throttleScrollContainer } = useBackBottom(scrollRef, scrollToBottom)
...@@ -31,7 +38,8 @@ const isShowContinueQuestion = computed(() => { ...@@ -31,7 +38,8 @@ const isShowContinueQuestion = computed(() => {
props.continuousQuestionStatus === 'default' && props.continuousQuestionStatus === 'default' &&
props.messageList.size > 1 && props.messageList.size > 1 &&
!props.isAnswerResponseLoading && !props.isAnswerResponseLoading &&
!props.createContinueQuestionsException !props.createContinueQuestionsException &&
!props.lastQuestionContent
) )
}) })
...@@ -67,6 +75,10 @@ function handleScrollToBottom() { ...@@ -67,6 +75,10 @@ function handleScrollToBottom() {
/> />
</div> </div>
<p v-show="isMobile && isAnswerResponseLoading" class="ml-1 mt-[7px] text-xs text-[#84868c]">
{{ t('common_module.dialogue_module.do_not_exit_page') }}
</p>
<div v-show="isShowContinueQuestion"> <div v-show="isShowContinueQuestion">
<ContinueQuestion :continuous-question-list="continuousQuestionList" /> <ContinueQuestion :continuous-question-list="continuousQuestionList" />
</div> </div>
......
...@@ -3,6 +3,7 @@ import { computed, onMounted, onUnmounted, ref, shallowRef } from 'vue' ...@@ -3,6 +3,7 @@ import { computed, onMounted, onUnmounted, ref, shallowRef } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { Howl } from 'howler' import { Howl } from 'howler'
import { useEventListener } from '@vueuse/core'
import type { ValueOf } from 'type-fest' import type { ValueOf } from 'type-fest'
import PageHeader from './components/mobile-page-header.vue' import PageHeader from './components/mobile-page-header.vue'
import Preamble from './components/preamble.vue' import Preamble from './components/preamble.vue'
...@@ -30,6 +31,30 @@ const userStore = useUserStore() ...@@ -30,6 +31,30 @@ const userStore = useUserStore()
const { isMobile } = useLayoutConfig() const { isMobile } = useLayoutConfig()
useEventListener(document, 'visibilitychange', () => {
if (document.visibilityState === 'hidden') {
handleExitPage()
handleAudioPause()
} else if (document.visibilityState === 'visible' && lastQuestionContent.value) {
window.$dialog.warning({
title: t('share_agent_module.create_agent_dialogue_title'),
content: t('common_module.dialogue_module.content_interrupted'),
negativeText: t('common_module.cancel_btn_text'),
positiveText: t('common_module.confirm_btn_text'),
onPositiveClick() {
footerInputRef.value?.handleMessageSend(lastQuestionContent.value)
lastQuestionContent.value = ''
},
onNegativeClick() {
lastQuestionContent.value = ''
},
onAfterLeave() {
lastQuestionContent.value = ''
},
})
}
})
const fullScreenLoading = ref(false) const fullScreenLoading = ref(false)
const agentId = ref('') const agentId = ref('')
const dialogsId = ref('') const dialogsId = ref('')
...@@ -51,6 +76,7 @@ const currentSoundCtl = shallowRef<Howl | null>(null) ...@@ -51,6 +76,7 @@ const currentSoundCtl = shallowRef<Howl | null>(null)
const isSoundCtlCreated = ref(false) const isSoundCtlCreated = ref(false)
const isAnswerResponseLoading = ref(false) const isAnswerResponseLoading = ref(false)
const createContinueQuestionsException = ref(false) const createContinueQuestionsException = ref(false)
const lastQuestionContent = ref('') // 上一次提问内容
const isEnableDocumentParse = computed(() => { const isEnableDocumentParse = computed(() => {
return agentApplicationConfig.value.knowledgeConfig.isDocumentParsing === 'Y' return agentApplicationConfig.value.knowledgeConfig.isDocumentParsing === 'Y'
...@@ -315,6 +341,18 @@ function handleInitSoundPlay() { ...@@ -315,6 +341,18 @@ function handleInitSoundPlay() {
}, },
}) })
} }
// 退出页面中断对话
function handleExitPage() {
if (messageList.value.size > 0 && isAnswerResponseLoading.value) {
const messageListArr = Array.from(messageList.value.values())
if (messageListArr.length >= 2) {
lastQuestionContent.value = messageListArr[messageListArr.length - 2]?.textContent || ''
}
footerInputRef.value?.errorMessageResponse()
}
}
</script> </script>
<template> <template>
...@@ -350,6 +388,7 @@ function handleInitSoundPlay() { ...@@ -350,6 +388,7 @@ function handleInitSoundPlay() {
:continuous-question-list="continueQuestionList" :continuous-question-list="continueQuestionList"
:is-answer-response-loading="isAnswerResponseLoading" :is-answer-response-loading="isAnswerResponseLoading"
:create-continue-questions-exception="createContinueQuestionsException" :create-continue-questions-exception="createContinueQuestionsException"
:last-question-content="lastQuestionContent"
@audio-play="handleAudioPlay" @audio-play="handleAudioPlay"
@audio-pause="handleAudioPause" @audio-pause="handleAudioPause"
/> />
......
...@@ -165,6 +165,8 @@ declare namespace I18n { ...@@ -165,6 +165,8 @@ declare namespace I18n {
overwrite_image_tip: string overwrite_image_tip: string
upload_image_size_error_message: string upload_image_size_error_message: string
upload_image_format_error_message: string upload_image_format_error_message: string
do_not_exit_page: string
content_interrupted: string
} }
data_table_module: { data_table_module: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment