feat: improve code formatting and add video list handling in chat components

v3.2
wxg0103 2025-10-15 10:23:37 +08:00
parent 629c6ee3a8
commit ef0713ecc6
6 changed files with 120 additions and 53 deletions

View File

@ -1,6 +1,7 @@
import { type Dict } from '@/api/type/common' import {type Dict} from '@/api/type/common'
import { type Ref } from 'vue' import {type Ref} from 'vue'
import bus from '@/bus' import bus from '@/bus'
interface ApplicationFormType { interface ApplicationFormType {
name?: string name?: string
desc?: string desc?: string
@ -35,6 +36,7 @@ interface ApplicationFormType {
tool_ids?: string[] tool_ids?: string[]
mcp_output_enable?: boolean mcp_output_enable?: boolean
} }
interface Chunk { interface Chunk {
real_node_id: string real_node_id: string
chat_id: string chat_id: string
@ -50,6 +52,7 @@ interface Chunk {
runtime_node_id: string runtime_node_id: string
child_node: any child_node: any
} }
interface chatType { interface chatType {
id: string id: string
problem_text: string problem_text: string
@ -82,6 +85,7 @@ interface chatType {
document_list: Array<any> document_list: Array<any>
image_list: Array<any> image_list: Array<any>
audio_list: Array<any> audio_list: Array<any>
video_list: Array<any>
other_list: Array<any> other_list: Array<any>
} }
} }
@ -95,6 +99,7 @@ interface Node {
index: number index: number
is_end: boolean is_end: boolean
} }
interface WriteNodeInfo { interface WriteNodeInfo {
current_node: any current_node: any
answer_text_list_index: number answer_text_list_index: number
@ -102,6 +107,7 @@ interface WriteNodeInfo {
divider_content?: Array<string> divider_content?: Array<string>
divider_reasoning_content?: Array<string> divider_reasoning_content?: Array<string>
} }
export class ChatRecordManage { export class ChatRecordManage {
id?: any id?: any
ms: number ms: number
@ -112,6 +118,7 @@ export class ChatRecordManage {
loading?: Ref<boolean> loading?: Ref<boolean>
node_list: Array<any> node_list: Array<any>
write_node_info?: WriteNodeInfo write_node_info?: WriteNodeInfo
constructor(chat: chatType, ms?: number, loading?: Ref<boolean>) { constructor(chat: chatType, ms?: number, loading?: Ref<boolean>) {
this.ms = ms ? ms : 10 this.ms = ms ? ms : 10
this.chat = chat this.chat = chat
@ -121,6 +128,7 @@ export class ChatRecordManage {
this.write_ed = false this.write_ed = false
this.node_list = [] this.node_list = []
} }
append_answer( append_answer(
chunk_answer: string, chunk_answer: string,
reasoning_content: string, reasoning_content: string,
@ -157,8 +165,9 @@ export class ChatRecordManage {
} }
} }
this.chat.answer_text = this.chat.answer_text + chunk_answer this.chat.answer_text = this.chat.answer_text + chunk_answer
bus.emit('change:answer', { record_id: this.chat.record_id, is_end: false }) bus.emit('change:answer', {record_id: this.chat.record_id, is_end: false})
} }
get_current_up_node(run_node: any) { get_current_up_node(run_node: any) {
const index = this.node_list.findIndex((item) => item == run_node) const index = this.node_list.findIndex((item) => item == run_node)
if (index > 0) { if (index > 0) {
@ -167,6 +176,7 @@ export class ChatRecordManage {
} }
return undefined return undefined
} }
get_run_node() { get_run_node() {
if ( if (
this.write_node_info && this.write_node_info &&
@ -225,6 +235,7 @@ export class ChatRecordManage {
} }
return undefined return undefined
} }
findIndex<T>(array: Array<T>, find: (item: T) => boolean, type: 'last' | 'index') { findIndex<T>(array: Array<T>, find: (item: T) => boolean, type: 'last' | 'index') {
let set_index = -1 let set_index = -1
for (let index = 0; index < array.length; index++) { for (let index = 0; index < array.length; index++) {
@ -238,13 +249,14 @@ export class ChatRecordManage {
} }
return set_index return set_index
} }
closeInterval() { closeInterval() {
this.chat.write_ed = true this.chat.write_ed = true
this.write_ed = true this.write_ed = true
if (this.loading) { if (this.loading) {
this.loading.value = false this.loading.value = false
} }
bus.emit('change:answer', { record_id: this.chat.record_id, is_end: true }) bus.emit('change:answer', {record_id: this.chat.record_id, is_end: true})
if (this.id) { if (this.id) {
clearInterval(this.id) clearInterval(this.id)
} }
@ -257,6 +269,7 @@ export class ChatRecordManage {
this.chat.answer_text_list.splice(last_index, 1) this.chat.answer_text_list.splice(last_index, 1)
} }
} }
write() { write() {
this.chat.is_stop = false this.chat.is_stop = false
this.is_stop = false this.is_stop = false
@ -277,21 +290,21 @@ export class ChatRecordManage {
} }
return return
} }
const { current_node, answer_text_list_index } = node_info const {current_node, answer_text_list_index} = node_info
if (current_node.buffer.length > 20) { if (current_node.buffer.length > 20) {
const context = current_node.is_end const context = current_node.is_end
? current_node.buffer.splice(0) ? current_node.buffer.splice(0)
: current_node.buffer.splice( : current_node.buffer.splice(
0, 0,
current_node.is_end ? undefined : current_node.buffer.length - 20, current_node.is_end ? undefined : current_node.buffer.length - 20,
) )
const reasoning_content = current_node.is_end const reasoning_content = current_node.is_end
? current_node.reasoning_content_buffer.splice(0) ? current_node.reasoning_content_buffer.splice(0)
: current_node.reasoning_content_buffer.splice( : current_node.reasoning_content_buffer.splice(
0, 0,
current_node.is_end ? undefined : current_node.reasoning_content_buffer.length - 20, current_node.is_end ? undefined : current_node.reasoning_content_buffer.length - 20,
) )
this.append_answer( this.append_answer(
context.join(''), context.join(''),
reasoning_content.join(''), reasoning_content.join(''),
@ -354,6 +367,7 @@ export class ChatRecordManage {
} }
}, this.ms) }, this.ms)
} }
stop() { stop() {
clearInterval(this.id) clearInterval(this.id)
this.is_stop = true this.is_stop = true
@ -362,13 +376,16 @@ export class ChatRecordManage {
this.loading.value = false this.loading.value = false
} }
} }
close() { close() {
this.is_close = true this.is_close = true
} }
open() { open() {
this.is_close = false this.is_close = false
this.is_stop = false this.is_stop = false
} }
appendChunk(chunk: Chunk) { appendChunk(chunk: Chunk) {
let n = this.node_list.find((item) => item.real_node_id == chunk.real_node_id) let n = this.node_list.find((item) => item.real_node_id == chunk.real_node_id)
if (n) { if (n) {
@ -401,6 +418,7 @@ export class ChatRecordManage {
n['is_end'] = true n['is_end'] = true
} }
} }
append(answer_text_block: string, reasoning_content?: string) { append(answer_text_block: string, reasoning_content?: string) {
let set_index = this.findIndex( let set_index = this.findIndex(
this.chat.answer_text_list, this.chat.answer_text_list,
@ -425,24 +443,28 @@ export class ChatManagement {
static addChatRecord(chat: chatType, ms: number, loading?: Ref<boolean>) { static addChatRecord(chat: chatType, ms: number, loading?: Ref<boolean>) {
this.chatMessageContainer[chat.id] = new ChatRecordManage(chat, ms, loading) this.chatMessageContainer[chat.id] = new ChatRecordManage(chat, ms, loading)
} }
static appendChunk(chatRecordId: string, chunk: Chunk) { static appendChunk(chatRecordId: string, chunk: Chunk) {
const chatRecord = this.chatMessageContainer[chatRecordId] const chatRecord = this.chatMessageContainer[chatRecordId]
if (chatRecord) { if (chatRecord) {
chatRecord.appendChunk(chunk) chatRecord.appendChunk(chunk)
} }
} }
static append(chatRecordId: string, content: string, reasoning_content?: string) { static append(chatRecordId: string, content: string, reasoning_content?: string) {
const chatRecord = this.chatMessageContainer[chatRecordId] const chatRecord = this.chatMessageContainer[chatRecordId]
if (chatRecord) { if (chatRecord) {
chatRecord.append(content, reasoning_content) chatRecord.append(content, reasoning_content)
} }
} }
static updateStatus(chatRecordId: string, code: number) { static updateStatus(chatRecordId: string, code: number) {
const chatRecord = this.chatMessageContainer[chatRecordId] const chatRecord = this.chatMessageContainer[chatRecordId]
if (chatRecord) { if (chatRecord) {
chatRecord.chat.status = code chatRecord.chat.status = code
} }
} }
/** /**
* *
* @param chatRecordId id * @param chatRecordId id
@ -453,12 +475,14 @@ export class ChatManagement {
chatRecord.write() chatRecord.write()
} }
} }
static open(chatRecordId: string) { static open(chatRecordId: string) {
const chatRecord = this.chatMessageContainer[chatRecordId] const chatRecord = this.chatMessageContainer[chatRecordId]
if (chatRecord) { if (chatRecord) {
chatRecord.open() chatRecord.open()
} }
} }
/** /**
* *
* @param chatRecordId id * @param chatRecordId id
@ -470,6 +494,7 @@ export class ChatManagement {
chatRecord.close() chatRecord.close()
} }
} }
/** /**
* *
* @param chatRecordId id * @param chatRecordId id
@ -481,6 +506,7 @@ export class ChatManagement {
chatRecord.stop() chatRecord.stop()
} }
} }
/** /**
* *
* @param chatRecordId id * @param chatRecordId id
@ -490,6 +516,7 @@ export class ChatManagement {
const chatRecord = this.chatMessageContainer[chatRecordId] const chatRecord = this.chatMessageContainer[chatRecordId]
return chatRecord ? chatRecord.is_close && chatRecord.write_ed : false return chatRecord ? chatRecord.is_close && chatRecord.write_ed : false
} }
/** /**
* *
* @param chatRecordId id * @param chatRecordId id
@ -499,6 +526,7 @@ export class ChatManagement {
const chatRecord = this.chatMessageContainer[chatRecordId] const chatRecord = this.chatMessageContainer[chatRecordId]
return chatRecord ? chatRecord.is_stop : false return chatRecord ? chatRecord.is_stop : false
} }
/** /**
* closestop * closestop
*/ */
@ -510,4 +538,5 @@ export class ChatManagement {
} }
} }
} }
export type { ApplicationFormType, chatType }
export type {ApplicationFormType, chatType}

View File

@ -1,6 +1,5 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.3335 3.33333C5.3335 2.59695 5.93045 2 6.66683 2H19.724C19.9008 2 20.0704 2.07024 20.1954 2.19526L26.4716 8.47141C26.5966 8.59643 26.6668 8.766 26.6668 8.94281V28.6667C26.6668 29.403 26.0699 30 25.3335 30H6.66683C5.93045 30 5.3335 29.403 5.3335 28.6667V3.33333Z" fill="#14C0FF"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M4.00018 2.5C4.00018 1.94772 4.4479 1.5 5.00018 1.5H14.7931C14.9257 1.5 15.0529 1.55268 15.1466 1.64645L19.8537 6.35355C19.9475 6.44732 20.0002 6.5745 20.0002 6.70711V21.5C20.0002 22.0523 19.5525 22.5 19.0002 22.5H5.00018C4.4479 22.5 4.00018 22.0523 4.00018 21.5V2.5Z" fill="#34C724"/>
<path d="M20 2.05988C20.072 2.09264 20.1383 2.13825 20.1953 2.19526L26.4714 8.4714C26.5284 8.52841 26.574 8.59467 26.6068 8.66666H21.3333C20.597 8.66666 20 8.06971 20 7.33333V2.05988Z" fill="#11A3D9"/> <path d="M15 1.54492C15.054 1.56949 15.1037 1.6037 15.1464 1.64646L19.8536 6.35357C19.8963 6.39632 19.9305 6.44602 19.9551 6.50001H16C15.4477 6.50001 15 6.0523 15 5.50001V1.54492Z" fill="#2CA91F"/>
<path d="M11.3335 16C12.4381 16 13.3335 15.1046 13.3335 14C13.3335 12.8954 12.4381 12 11.3335 12C10.2289 12 9.3335 12.8954 9.3335 14C9.3335 15.1046 10.2289 16 11.3335 16Z" fill="white"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 11.5C7.5 11.2239 7.72386 11 8 11H13.3971C13.6733 11 13.8971 11.2239 13.8971 11.5V12.1723L15.8207 11.4333C15.9744 11.3742 16.1474 11.3946 16.2831 11.4879C16.4189 11.5812 16.5 11.7353 16.5 11.9V16.3C16.5 16.4647 16.4189 16.6188 16.2831 16.7121C16.1474 16.8054 15.9744 16.8258 15.8207 16.7667L13.8971 16.0277V16.7C13.8971 16.9761 13.6733 17.2 13.3971 17.2H8C7.72386 17.2 7.5 16.9761 7.5 16.7V11.5ZM9.25 13.5C9.66421 13.5 10 13.1642 10 12.75C10 12.3358 9.66421 12 9.25 12C8.83579 12 8.5 12.3358 8.5 12.75C8.5 13.1642 8.83579 13.5 9.25 13.5Z" fill="white"/>
<path d="M22.2785 14.9317C22.4218 14.7884 22.6668 14.8899 22.6668 15.0925V24.0645C22.6668 24.1901 22.565 24.2919 22.4394 24.2919H13.4674L13.4587 24.2918H9.56142C9.35877 24.2918 9.25728 24.0468 9.40058 23.9035L14.366 18.938C14.4549 18.8492 14.5989 18.8492 14.6877 18.938L16.48 20.7302L22.2785 14.9317Z" fill="white"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -180,8 +180,9 @@
<video <video
v-if="item.url" v-if="item.url"
:src="item.url" :src="item.url"
controls style="width: 40px; height: 40px; display: block" controls style="width: 100px; display: block"
class="border-r-6" class="border-r-6"
autoplay
/> />
</div> </div>
</template> </template>

View File

@ -3,7 +3,7 @@
<div class="flex-between cursor" @click="data['show'] = !data['show']"> <div class="flex-between cursor" @click="data['show'] = !data['show']">
<div class="flex align-center"> <div class="flex align-center">
<el-icon class="mr-8 arrow-icon" :class="data['show'] ? 'rotate-90' : ''"> <el-icon class="mr-8 arrow-icon" :class="data['show'] ? 'rotate-90' : ''">
<CaretRight /> <CaretRight/>
</el-icon> </el-icon>
<component <component
:is="iconComponent(`${data.type}-icon`)" :is="iconComponent(`${data.type}-icon`)"
@ -24,14 +24,14 @@
data.type === WorkflowType.Application || data.type === WorkflowType.Application ||
data.type == WorkflowType.IntentNode data.type == WorkflowType.IntentNode
" "
>{{ data?.message_tokens + data?.answer_tokens }} tokens</span >{{ data?.message_tokens + data?.answer_tokens }} tokens</span
> >
<span class="mr-16 color-secondary">{{ data?.run_time?.toFixed(2) || 0.0 }} s</span> <span class="mr-16 color-secondary">{{ data?.run_time?.toFixed(2) || 0.0 }} s</span>
<el-icon class="color-success" :size="16" v-if="data.status === 200"> <el-icon class="color-success" :size="16" v-if="data.status === 200">
<CircleCheck /> <CircleCheck/>
</el-icon> </el-icon>
<el-icon class="color-danger" :size="16" v-else> <el-icon class="color-danger" :size="16" v-else>
<CircleClose /> <CircleClose/>
</el-icon> </el-icon>
</div> </div>
</div> </div>
@ -64,7 +64,7 @@
<template v-for="(f, i) in data.document_list" :key="i"> <template v-for="(f, i) in data.document_list" :key="i">
<el-card shadow="never" style="--el-card-padding: 8px" class="file cursor"> <el-card shadow="never" style="--el-card-padding: 8px" class="file cursor">
<div class="flex align-center"> <div class="flex align-center">
<img :src="getImgUrl(f && f?.name)" alt="" width="24" /> <img :src="getImgUrl(f && f?.name)" alt="" width="24"/>
<div class="ml-4 ellipsis" :title="f && f?.name"> <div class="ml-4 ellipsis" :title="f && f?.name">
{{ f && f?.name }} {{ f && f?.name }}
</div> </div>
@ -109,7 +109,7 @@
<template v-for="(f, i) in data.other_list" :key="i"> <template v-for="(f, i) in data.other_list" :key="i">
<el-card shadow="never" style="--el-card-padding: 8px" class="file cursor"> <el-card shadow="never" style="--el-card-padding: 8px" class="file cursor">
<div class="flex align-center"> <div class="flex align-center">
<img :src="getImgUrl(f && f?.name)" alt="" width="24" /> <img :src="getImgUrl(f && f?.name)" alt="" width="24"/>
<div class="ml-4 ellipsis" :title="f && f?.name"> <div class="ml-4 ellipsis" :title="f && f?.name">
{{ f && f?.name }} {{ f && f?.name }}
</div> </div>
@ -448,7 +448,8 @@
<template v-if="data.type === WorkflowType.FormNode"> <template v-if="data.type === WorkflowType.FormNode">
<div class="card-never border-r-6"> <div class="card-never border-r-6">
<h5 class="p-8-12"> <h5 class="p-8-12">
{{ $t('common.param.outputParam') {{
$t('common.param.outputParam')
}}<span style="color: #f54a45">{{ }}<span style="color: #f54a45">{{
data.is_submit ? '' : `(${$t('chat.executionDetails.noSubmit')})` data.is_submit ? '' : `(${$t('chat.executionDetails.noSubmit')})`
}}</span> }}</span>
@ -500,7 +501,7 @@
class="border-r-6 mr-8" class="border-r-6 mr-8"
/> />
<span v-else>{{ h.text }}<br /></span> <span v-else>{{ h.text }}<br/></span>
</template> </template>
</span> </span>
@ -555,7 +556,7 @@
</div> </div>
</template> </template>
<!-- 视频理解 --> <!-- 视频理解 -->
<template v-if="data.type == WorkflowType.VideoUnderstandNode"> <template v-if="data.type == WorkflowType.VideoUnderstandNode">
<div class="card-never border-r-6" v-if="data.type !== WorkflowType.Application"> <div class="card-never border-r-6" v-if="data.type !== WorkflowType.Application">
<h5 class="p-8-12"> <h5 class="p-8-12">
{{ $t('views.application.form.roleSettings.label') }} {{ $t('views.application.form.roleSettings.label') }}
@ -577,7 +578,7 @@
<span v-if="Array.isArray(history.content)"> <span v-if="Array.isArray(history.content)">
<template v-for="(h, i) in history.content" :key="i"> <template v-for="(h, i) in history.content" :key="i">
<el-image <video
v-if="h.type === 'video_url'" v-if="h.type === 'video_url'"
:src="h.video_url.url" :src="h.video_url.url"
alt="" alt=""
@ -586,7 +587,7 @@
class="border-r-6 mr-8" class="border-r-6 mr-8"
/> />
<span v-else>{{ h.text }}<br /></span> <span v-else>{{ h.text }}<br/></span>
</template> </template>
</span> </span>
@ -601,15 +602,15 @@
{{ $t('chat.executionDetails.currentChat') }} {{ $t('chat.executionDetails.currentChat') }}
</h5> </h5>
<div class="p-8-12 border-t-dashed lighter pre-wrap"> <div class="p-8-12 border-t-dashed lighter pre-wrap">
<div v-if="data.video_url?.length > 0"> <div v-if="data.video_list?.length > 0">
<el-space wrap> <el-space wrap>
<template v-for="(f, i) in data.video_url" :key="i"> <template v-for="(f, i) in data.video_list" :key="i">
<el-image <video
:src="f.url" :src="f.url"
alt="" style="width: 100px; display: block"
fit="cover"
style="width: 40px; height: 40px; display: block"
class="border-r-6" class="border-r-6"
autoplay
controls
/> />
</template> </template>
</el-space> </el-space>
@ -905,7 +906,7 @@
<template v-if="data.type === WorkflowType.LoopNode"> <template v-if="data.type === WorkflowType.LoopNode">
<el-radio-group v-model="currentLoopNode" class="app-radio-button-group mb-8"> <el-radio-group v-model="currentLoopNode" class="app-radio-button-group mb-8">
<template v-for="(loop, loopIndex) in data.loop_node_data" :key="loopIndex"> <template v-for="(loop, loopIndex) in data.loop_node_data" :key="loopIndex">
<el-radio-button :label="loopIndex" :value="loopIndex" /> <el-radio-button :label="loopIndex" :value="loopIndex"/>
</template> </template>
</el-radio-group> </el-radio-group>
<template <template
@ -993,15 +994,17 @@
</el-card> </el-card>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed } from 'vue' import {ref, computed} from 'vue'
import ParagraphCard from '@/components/ai-chat/component/knowledge-source-component/ParagraphCard.vue' import ParagraphCard
from '@/components/ai-chat/component/knowledge-source-component/ParagraphCard.vue'
import DynamicsForm from '@/components/dynamics-form/index.vue' import DynamicsForm from '@/components/dynamics-form/index.vue'
import { iconComponent } from '@/workflow/icons/utils' import {iconComponent} from '@/workflow/icons/utils'
import { WorkflowType } from '@/enums/application' import {WorkflowType} from '@/enums/application'
import { getImgUrl } from '@/utils/common' import {getImgUrl} from '@/utils/common'
import { arraySort } from '@/utils/array' import {arraySort} from '@/utils/array'
import {t} from '@/locales'
import { t } from '@/locales'
const props = defineProps<{ const props = defineProps<{
data: any data: any
}>() }>()

View File

@ -9,12 +9,12 @@
<el-card shadow="never" style="--el-card-padding: 8px" class="download-file cursor"> <el-card shadow="never" style="--el-card-padding: 8px" class="download-file cursor">
<div class="download-button flex align-center" @click="downloadFile(item)"> <div class="download-button flex align-center" @click="downloadFile(item)">
<el-icon class="mr-4"> <el-icon class="mr-4">
<Download /> <Download/>
</el-icon> </el-icon>
{{ $t('chat.download') }} {{ $t('chat.download') }}
</div> </div>
<div class="show flex align-center"> <div class="show flex align-center">
<img :src="getImgUrl(item && item?.name)" alt="" width="24" /> <img :src="getImgUrl(item && item?.name)" alt="" width="24"/>
<div class="ml-4 ellipsis-1" :title="item && item?.name"> <div class="ml-4 ellipsis-1" :title="item && item?.name">
{{ item && item?.name }} {{ item && item?.name }}
</div> </div>
@ -57,18 +57,33 @@
</template> </template>
</el-space> </el-space>
</div> </div>
<div class="mb-8" v-if="video_list.length">
<el-space wrap>
<template v-for="(item, index) in video_list" :key="index">
<div class="file cursor border-r-6" v-if="item.url">
<video
:src="item.url"
style="width: 170px; display: block"
class="border-r-6"
controls
autoplay
/>
</div>
</template>
</el-space>
</div>
<div class="mb-8" v-if="other_list.length"> <div class="mb-8" v-if="other_list.length">
<el-space wrap class="w-full media-file-width"> <el-space wrap class="w-full media-file-width">
<template v-for="(item, index) in other_list" :key="index"> <template v-for="(item, index) in other_list" :key="index">
<el-card shadow="never" style="--el-card-padding: 8px" class="download-file cursor"> <el-card shadow="never" style="--el-card-padding: 8px" class="download-file cursor">
<div class="download-button flex align-center" @click="downloadFile(item)"> <div class="download-button flex align-center" @click="downloadFile(item)">
<el-icon class="mr-4"> <el-icon class="mr-4">
<Download /> <Download/>
</el-icon> </el-icon>
{{ $t('chat.download') }} {{ $t('chat.download') }}
</div> </div>
<div class="show flex align-center"> <div class="show flex align-center">
<img :src="getImgUrl(item && item?.name)" alt="" width="24" /> <img :src="getImgUrl(item && item?.name)" alt="" width="24"/>
<div class="ml-4 ellipsis-1" :title="item && item?.name"> <div class="ml-4 ellipsis-1" :title="item && item?.name">
{{ item && item?.name }} {{ item && item?.name }}
</div> </div>
@ -89,16 +104,17 @@
style="width: 28px; height: 28px; display: block" style="width: 28px; height: 28px; display: block"
/> />
<el-avatar v-else :size="28"> <el-avatar v-else :size="28">
<img src="@/assets/user-icon.svg" style="width: 50%" alt="" /> <img src="@/assets/user-icon.svg" style="width: 50%" alt=""/>
</el-avatar> </el-avatar>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { type chatType } from '@/api/type/application' import {type chatType} from '@/api/type/application'
import { getImgUrl, downloadByURL } from '@/utils/common' import {getImgUrl, downloadByURL} from '@/utils/common'
import { getAttrsArray } from '@/utils/array' import {getAttrsArray} from '@/utils/array'
import { onMounted, computed } from 'vue' import {onMounted, computed} from 'vue'
const props = defineProps<{ const props = defineProps<{
application: any application: any
chatRecord: chatType chatRecord: chatType
@ -127,6 +143,15 @@ const image_list = computed(() => {
) )
return startNode?.image_list || [] return startNode?.image_list || []
}) })
const video_list = computed(() => {
if (props.chatRecord?.upload_meta) {
return props.chatRecord.upload_meta?.video_list || []
}
const startNode = props.chatRecord.execution_details?.find(
(detail) => detail.type === 'start-node',
)
return startNode?.video_list || []
})
const audio_list = computed(() => { const audio_list = computed(() => {
if (props.chatRecord?.upload_meta) { if (props.chatRecord?.upload_meta) {
return props.chatRecord.upload_meta?.audio_list || [] return props.chatRecord.upload_meta?.audio_list || []
@ -154,11 +179,13 @@ const getClassName = computed(() => {
? `media_${other_list.value.length}` ? `media_${other_list.value.length}`
: `media_0` : `media_0`
}) })
function downloadFile(item: any) { function downloadFile(item: any) {
downloadByURL(item.url, item.name) downloadByURL(item.url, item.name)
} }
onMounted(() => {}) onMounted(() => {
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.question-content { .question-content {
@ -196,21 +223,26 @@ onMounted(() => {})
display: none; display: none;
} }
} }
.media-file-width { .media-file-width {
:deep(.el-space__item) { :deep(.el-space__item) {
width: 49% !important; width: 49% !important;
} }
} }
.media_2 { .media_2 {
flex: 1; flex: 1;
} }
.media_0 { .media_0 {
flex: inherit; flex: inherit;
} }
.media_1 { .media_1 {
width: 50%; width: 50%;
} }
} }
@media only screen and (max-width: 768px) { @media only screen and (max-width: 768px) {
.question-content { .question-content {
.media-file-width { .media-file-width {
@ -218,11 +250,13 @@ onMounted(() => {})
min-width: 100% !important; min-width: 100% !important;
} }
} }
.media_1 { .media_1 {
width: 100%; width: 100%;
} }
} }
} }
.debug-ai-chat { .debug-ai-chat {
.question-content { .question-content {
.media-file-width { .media-file-width {
@ -230,6 +264,7 @@ onMounted(() => {})
min-width: 100% !important; min-width: 100% !important;
} }
} }
.media_1 { .media_1 {
width: 100%; width: 100%;
} }

View File

@ -27,7 +27,7 @@ export default {
RERANKER: '重排模型', RERANKER: '重排模型',
STT: '語音辨識', STT: '語音辨識',
TTS: '語音合成', TTS: '語音合成',
IMAGE: '圖片理解', IMAGE: '視覺理解',
TTI: '圖片生成', TTI: '圖片生成',
TTV: '文生視頻', TTV: '文生視頻',
ITV: '圖生視頻', ITV: '圖生視頻',