feat: 对话框
This commit is contained in:
parent
4c3dbbf6af
commit
f669ac2b35
@ -7,4 +7,9 @@ interface ApplicationFormType {
|
|||||||
example?: string[]
|
example?: string[]
|
||||||
dataset_id_list: string[]
|
dataset_id_list: string[]
|
||||||
}
|
}
|
||||||
export type { ApplicationFormType }
|
interface chatType {
|
||||||
|
id: string
|
||||||
|
problem_text: string
|
||||||
|
answer_text: string
|
||||||
|
}
|
||||||
|
export type { ApplicationFormType, chatType }
|
||||||
|
|||||||
@ -1,15 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ai-dialog p-24">
|
<div class="ai-dialog p-24">
|
||||||
<el-scrollbar>
|
<el-scrollbar ref="scrollDiv">
|
||||||
<div class="ai-dialog__content">
|
<div ref="dialogScrollbar" class="ai-dialog__content">
|
||||||
<div class="item-content mb-16">
|
<div class="item-content mb-16">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<AppAvatar class="avatar-gradient">
|
<AppAvatar class="avatar-gradient">
|
||||||
<img src="@/assets/icon_robot.svg" style="width: 54%" alt="" />
|
<img src="@/assets/icon_robot.svg" style="width: 54%" alt="" />
|
||||||
</AppAvatar>
|
</AppAvatar>
|
||||||
<!-- <AppAvatar>
|
|
||||||
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
|
||||||
</AppAvatar> -->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@ -36,28 +33,35 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-content mb-16">
|
<template v-for="(item, index) in chatList" :key="index">
|
||||||
<div class="avatar">
|
<!-- 问题 -->
|
||||||
<AppAvatar>
|
<div class="item-content mb-16 lighter">
|
||||||
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
<div class="avatar">
|
||||||
</AppAvatar>
|
<AppAvatar>
|
||||||
</div>
|
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
||||||
<div class="content">
|
</AppAvatar>
|
||||||
<div class="text">
|
</div>
|
||||||
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
<div class="content">
|
||||||
|
<div class="text">
|
||||||
|
{{ item.problem_text }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- 回答 -->
|
||||||
<div class="item-content mb-16">
|
<div class="item-content mb-16 lighter">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<AppAvatar class="avatar-gradient">
|
<AppAvatar class="avatar-gradient">
|
||||||
<img src="@/assets/icon_robot.svg" style="width: 54%" alt="" />
|
<img src="@/assets/icon_robot.svg" style="width: 54%" alt="" />
|
||||||
</AppAvatar>
|
</AppAvatar>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="flex" v-if="!item.answer_text">
|
||||||
|
<el-card shadow="always" class="dialog-card"> {{ '回答中...' }} </el-card>
|
||||||
|
</div>
|
||||||
|
<el-card v-else shadow="always" class="dialog-card"> {{ item.answer_text }} </el-card>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
</template>
|
||||||
<el-card shadow="always" class="dialog-card"> XXXXXXXXX </el-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
<div class="ai-dialog__operate p-24">
|
<div class="ai-dialog__operate p-24">
|
||||||
@ -67,13 +71,15 @@
|
|||||||
type="textarea"
|
type="textarea"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
:autosize="{ minRows: 1, maxRows: 8 }"
|
:autosize="{ minRows: 1, maxRows: 8 }"
|
||||||
|
@keydown.enter="sendChatHandle($event)"
|
||||||
|
:disabled="loading"
|
||||||
/>
|
/>
|
||||||
<div class="operate" v-loading="loading">
|
<div class="operate" v-loading="loading">
|
||||||
<el-button
|
<el-button
|
||||||
text
|
text
|
||||||
class="sent-button"
|
class="sent-button"
|
||||||
:disabled="!(inputValue && data?.name && data?.model_id)"
|
:disabled="!(inputValue && data?.name && data?.model_id)"
|
||||||
@click="chatMessage"
|
@click="sendChatHandle"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-show="!(inputValue && data?.name && data?.model_id)"
|
v-show="!(inputValue && data?.name && data?.model_id)"
|
||||||
@ -85,7 +91,6 @@
|
|||||||
src="@/assets/icon_send_colorful.svg"
|
src="@/assets/icon_send_colorful.svg"
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
<!-- <AppIcon iconName="app-send"></AppIcon> -->
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -93,22 +98,40 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref, nextTick, onUpdated } from 'vue'
|
||||||
import applicationApi from '@/api/application'
|
import applicationApi from '@/api/application'
|
||||||
|
import type { chatType } from '@/api/type/application'
|
||||||
|
import { randomId } from '@/utils/utils'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {}
|
default: () => {}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const scrollDiv = ref()
|
||||||
|
const dialogScrollbar = ref()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const inputValue = ref('')
|
const inputValue = ref('')
|
||||||
const chartOpenId = ref('')
|
const chartOpenId = ref('')
|
||||||
|
const chatList = ref<chatType[]>([])
|
||||||
|
|
||||||
function quickProblemHandel(val: string) {
|
function quickProblemHandel(val: string) {
|
||||||
inputValue.value = val
|
inputValue.value = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendChatHandle(event: any) {
|
||||||
|
if (!event.ctrlKey) {
|
||||||
|
// 如果没有按下组合键ctrl,则会阻止默认事件
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
chatMessage()
|
||||||
|
} else {
|
||||||
|
// 如果同时按下ctrl+回车键,则会换行
|
||||||
|
inputValue.value += '\n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对话
|
* 对话
|
||||||
*/
|
*/
|
||||||
@ -131,10 +154,18 @@ function getChartOpenId() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function chatMessage() {
|
function chatMessage() {
|
||||||
|
loading.value = true
|
||||||
if (!chartOpenId.value) {
|
if (!chartOpenId.value) {
|
||||||
getChartOpenId()
|
getChartOpenId()
|
||||||
} else {
|
} else {
|
||||||
applicationApi.postChatMessage(chartOpenId.value, inputValue.value).then(async (response) => {
|
applicationApi.postChatMessage(chartOpenId.value, inputValue.value).then(async (response) => {
|
||||||
|
const randomNum = randomId()
|
||||||
|
chatList.value.push({
|
||||||
|
id: randomNum,
|
||||||
|
problem_text: inputValue.value,
|
||||||
|
answer_text: ''
|
||||||
|
})
|
||||||
|
inputValue.value = ''
|
||||||
const reader = response.body.getReader()
|
const reader = response.body.getReader()
|
||||||
while (true) {
|
while (true) {
|
||||||
const { done, value } = await reader.read()
|
const { done, value } = await reader.read()
|
||||||
@ -144,11 +175,26 @@ function chatMessage() {
|
|||||||
}
|
}
|
||||||
const decoder = new TextDecoder('utf-8')
|
const decoder = new TextDecoder('utf-8')
|
||||||
const str = decoder.decode(value, { stream: true })
|
const str = decoder.decode(value, { stream: true })
|
||||||
console.log('value', JSON.parse(str.replace('data:', '')))
|
// console.log(JSON?.parse(str.replace('data:', '')))
|
||||||
|
const content = JSON?.parse(str.replace('data:', ''))?.content
|
||||||
|
if (content) {
|
||||||
|
chatList.value[chatList.value.findIndex((v) => v.id === randomNum)].answer_text += content
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 滚动到底部
|
||||||
|
function handleScrollBottom() {
|
||||||
|
nextTick(() => {
|
||||||
|
scrollDiv.value.setScrollTop(dialogScrollbar.value.scrollHeight)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdated(() => {
|
||||||
|
handleScrollBottom()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.ai-dialog {
|
.ai-dialog {
|
||||||
@ -160,6 +206,7 @@ function chatMessage() {
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
color: var(--app-text-color);
|
||||||
&__content {
|
&__content {
|
||||||
width: 99%;
|
width: 99%;
|
||||||
padding-bottom: 96px;
|
padding-bottom: 96px;
|
||||||
|
|||||||
@ -38,7 +38,6 @@ instance.interceptors.request.use(
|
|||||||
//设置响应拦截器
|
//设置响应拦截器
|
||||||
instance.interceptors.response.use(
|
instance.interceptors.response.use(
|
||||||
(response: any) => {
|
(response: any) => {
|
||||||
console.log('instance_response', response)
|
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
if (response.status !== 200 && !(response.data instanceof Blob)) {
|
if (response.status !== 200 && !(response.data instanceof Blob)) {
|
||||||
MsgError(response.data.message)
|
MsgError(response.data.message)
|
||||||
|
|||||||
@ -19,6 +19,13 @@ export function filesize(size: number) {
|
|||||||
return (size / Math.pow(num, 4)).toFixed(2) + 'T' //T
|
return (size / Math.pow(num, 4)).toFixed(2) + 'T' //T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
随机id
|
||||||
|
*/
|
||||||
|
export const randomId = function () {
|
||||||
|
return Math.floor(Math.random() * 10000) + ''
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
获取文件后缀
|
获取文件后缀
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user