feat: 图片引用
This commit is contained in:
@@ -155,6 +155,9 @@ export default {
|
|||||||
deleteSuccess: 'Successfully deleted',
|
deleteSuccess: 'Successfully deleted',
|
||||||
thinking: 'Thinking...',
|
thinking: 'Thinking...',
|
||||||
thinkComplete: 'Thinking complete.',
|
thinkComplete: 'Thinking complete.',
|
||||||
|
quote: 'Quote',
|
||||||
|
delete: 'Delete',
|
||||||
|
edit: 'Edit',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Version Tree
|
// Version Tree
|
||||||
|
|||||||
@@ -149,7 +149,10 @@ export default {
|
|||||||
Download: '下载',
|
Download: '下载',
|
||||||
deleteSuccess: '删除成功',
|
deleteSuccess: '删除成功',
|
||||||
thinking:'已思考',
|
thinking:'已思考',
|
||||||
thinkComplete: '思考完成。'
|
thinkComplete: '思考完成。',
|
||||||
|
quote: '引用',
|
||||||
|
delete: '删除',
|
||||||
|
edit: '编辑',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Version Tree
|
// Version Tree
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ type InitialProjectData = {
|
|||||||
style: string
|
style: string
|
||||||
useReport:boolean
|
useReport:boolean
|
||||||
needSuggestion:boolean
|
needSuggestion:boolean
|
||||||
|
quoteList: Array<string>
|
||||||
|
tempImages: any[]
|
||||||
}
|
}
|
||||||
export const useAgentStore = defineStore('agent', () => {
|
export const useAgentStore = defineStore('agent', () => {
|
||||||
const initialProjectData = ref<InitialProjectData | null>(null)
|
const initialProjectData = ref<InitialProjectData | null>(null)
|
||||||
|
|||||||
@@ -64,7 +64,8 @@
|
|||||||
region: '',
|
region: '',
|
||||||
style: ''
|
style: ''
|
||||||
},
|
},
|
||||||
imageUrlList: []
|
imageUrlList: [],
|
||||||
|
quotaUrl: []
|
||||||
})
|
})
|
||||||
|
|
||||||
const sketchList = ref([])
|
const sketchList = ref([])
|
||||||
@@ -110,7 +111,8 @@
|
|||||||
text: initialData.text,
|
text: initialData.text,
|
||||||
images: initialData.images,
|
images: initialData.images,
|
||||||
useReport: initialData.useReport,
|
useReport: initialData.useReport,
|
||||||
tempImages: initialData.tempImages
|
tempImages: initialData.tempImages,
|
||||||
|
quoteList: initialData.quoteList
|
||||||
})
|
})
|
||||||
// 更新 configParams
|
// 更新 configParams
|
||||||
|
|
||||||
@@ -125,6 +127,7 @@
|
|||||||
images: Array<{ url: string; name: string }>
|
images: Array<{ url: string; name: string }>
|
||||||
tempImages: any[]
|
tempImages: any[]
|
||||||
useReport: boolean
|
useReport: boolean
|
||||||
|
quoteList: Array<string>
|
||||||
},
|
},
|
||||||
skipUserMessage = false
|
skipUserMessage = false
|
||||||
) => {
|
) => {
|
||||||
@@ -136,14 +139,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
params.imageUrlList = message.images || []
|
params.imageUrlList = message.images || []
|
||||||
|
params.quotaUrl = message.quoteList || []
|
||||||
// 如果不是重新生成模式,则添加用户消息到列表
|
// 如果不是重新生成模式,则添加用户消息到列表
|
||||||
if (!skipUserMessage) {
|
if (!skipUserMessage) {
|
||||||
messageList.value.push({
|
messageList.value.push({
|
||||||
id: messageList.value.length + 1,
|
id: messageList.value.length + 1,
|
||||||
text: message.text,
|
text: message.text,
|
||||||
isUser: true,
|
isUser: true,
|
||||||
imageUrls: message.tempImages
|
imageUrls: message.tempImages.concat(message.quoteList)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,6 +226,8 @@
|
|||||||
let hasReportStarted = false // 标记 report 是否已经开始
|
let hasReportStarted = false // 标记 report 是否已经开始
|
||||||
|
|
||||||
let hasSketchEvent = false
|
let hasSketchEvent = false
|
||||||
|
let hasReportEvent = false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let flag = true
|
let flag = true
|
||||||
while (flag) {
|
while (flag) {
|
||||||
@@ -231,6 +236,9 @@
|
|||||||
if (hasSketchEvent) {
|
if (hasSketchEvent) {
|
||||||
aiMessage.text += `<slot slot-name="sketch"></slot>`
|
aiMessage.text += `<slot slot-name="sketch"></slot>`
|
||||||
}
|
}
|
||||||
|
if (hasReportEvent) {
|
||||||
|
aiMessage.text += `<slot slot-name="card" title="Report" content="Report"></slot>`
|
||||||
|
}
|
||||||
|
|
||||||
aiMessage.streaming = false
|
aiMessage.streaming = false
|
||||||
aiMessage.loading = false
|
aiMessage.loading = false
|
||||||
@@ -256,7 +264,8 @@
|
|||||||
|
|
||||||
if (!hasReportStarted && eventName === 'report') {
|
if (!hasReportStarted && eventName === 'report') {
|
||||||
isGeneratingReport.value = true
|
isGeneratingReport.value = true
|
||||||
contentBody += `<slot slot-name="card" title="Report" content="Report"></slot>`
|
hasReportEvent = true
|
||||||
|
// contentBody += `<slot slot-name="card" title="Report" content="Report"></slot>`
|
||||||
hasReportStarted = true
|
hasReportStarted = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,7 +597,7 @@
|
|||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
ancestorsList.forEach((item) => {
|
ancestorsList.forEach((item) => {
|
||||||
if (item.image_url) {
|
if (item.image_url && item.role !== 'user') {
|
||||||
item.text += `<slot slot-name="sketch"></slot>`
|
item.text += `<slot slot-name="sketch"></slot>`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -129,7 +129,7 @@
|
|||||||
}>()
|
}>()
|
||||||
|
|
||||||
// watch(
|
// watch(
|
||||||
// () => props.content,
|
// () => props,
|
||||||
// (newVal) => {
|
// (newVal) => {
|
||||||
// console.log('newVal-----', newVal)
|
// console.log('newVal-----', newVal)
|
||||||
// },
|
// },
|
||||||
@@ -139,8 +139,12 @@
|
|||||||
const emit = defineEmits(['regenerate'])
|
const emit = defineEmits(['regenerate'])
|
||||||
|
|
||||||
const imageList = computed(() => {
|
const imageList = computed(() => {
|
||||||
const { imageUrls } = props.content
|
const { imageUrls, role } = props.content
|
||||||
const list = []
|
const list = []
|
||||||
|
if (role === 'user') {
|
||||||
|
const quotaList = props.content.image_url ?? []
|
||||||
|
list.push(...quotaList)
|
||||||
|
}
|
||||||
if (!imageUrls || imageUrls.length === 0) return list
|
if (!imageUrls || imageUrls.length === 0) return list
|
||||||
imageUrls.forEach((item) => {
|
imageUrls.forEach((item) => {
|
||||||
if (typeof item === 'string') {
|
if (typeof item === 'string') {
|
||||||
|
|||||||
@@ -13,12 +13,15 @@
|
|||||||
<Menu />
|
<Menu />
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item class="sketch-item flex align-center">
|
<el-dropdown-item
|
||||||
|
class="sketch-item flex align-center"
|
||||||
|
@click="handleClickQuote(item)"
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src="@/assets/images/restore-sketch.png"
|
src="@/assets/images/restore-sketch.png"
|
||||||
class="dropdown-icon restore"
|
class="dropdown-icon restore"
|
||||||
/>
|
/>
|
||||||
<span class="dropdown-txt">Quote</span>
|
<span class="dropdown-txt">{{ $t('agent.quote') }}</span>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
class="sketch-item flex align-center"
|
class="sketch-item flex align-center"
|
||||||
@@ -28,7 +31,7 @@
|
|||||||
src="@/assets/images/delete.png"
|
src="@/assets/images/delete.png"
|
||||||
class="dropdown-icon delete"
|
class="dropdown-icon delete"
|
||||||
/>
|
/>
|
||||||
<span class="dropdown-txt del">Delete</span>
|
<span class="dropdown-txt del">{{ $t('agent.delete') }}</span>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
@@ -37,7 +40,7 @@
|
|||||||
class="edit-btn flex align-center space-between"
|
class="edit-btn flex align-center space-between"
|
||||||
@click="handleClickEdit(item)"
|
@click="handleClickEdit(item)"
|
||||||
>
|
>
|
||||||
<div>Edit</div>
|
<div>{{ $t('agent.edit') }}</div>
|
||||||
<img src="@/assets/images/arrow-top-right.png" />
|
<img src="@/assets/images/arrow-top-right.png" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 已加载完成的 sketch 显示实际图片 -->
|
<!-- 已加载完成的 sketch 显示实际图片 -->
|
||||||
@@ -218,6 +221,12 @@
|
|||||||
myEvent.emit('openFlowCanvas', { url, imgId, nodeId })
|
myEvent.emit('openFlowCanvas', { url, imgId, nodeId })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleClickQuote = (item) => {
|
||||||
|
console.log(item)
|
||||||
|
const url = Object.values(item)[0]
|
||||||
|
MyEvent.emit('quote', url)
|
||||||
|
}
|
||||||
|
|
||||||
const handleClickDelete = (item: string | Object) => {
|
const handleClickDelete = (item: string | Object) => {
|
||||||
deleteSketchFlowCanvas({
|
deleteSketchFlowCanvas({
|
||||||
id: Object.keys(item)[0],
|
id: Object.keys(item)[0],
|
||||||
|
|||||||
@@ -48,8 +48,12 @@
|
|||||||
}
|
}
|
||||||
&.is-sketch {
|
&.is-sketch {
|
||||||
background: url('@/assets/images/sketch-card.png') no-repeat;
|
background: url('@/assets/images/sketch-card.png') no-repeat;
|
||||||
background-size: contain;
|
|
||||||
padding: 2rem 3rem;
|
padding: 2rem 3rem;
|
||||||
|
max-width: 52.5rem;
|
||||||
|
height: 8rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
min-height: initial;
|
||||||
.report-card-header {
|
.report-card-header {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
:deep(.report-card) {
|
|
||||||
width: 52.5rem;
|
|
||||||
height: 8rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,15 +2,17 @@
|
|||||||
<div class="assist-input-wrapper flex flex-col" :class="{ agent: isAgentMode }">
|
<div class="assist-input-wrapper flex flex-col" :class="{ agent: isAgentMode }">
|
||||||
<div class="animate-container flex-1 flex flex-col">
|
<div class="animate-container flex-1 flex flex-col">
|
||||||
<div class="scroll-content flex-col">
|
<div class="scroll-content flex-col">
|
||||||
<div v-if="uploadedImages.length > 0" class="image-preview-list flex wrap">
|
<div
|
||||||
|
v-if="uploadedImages.length > 0 || quoteList.length > 0"
|
||||||
|
class="image-preview-list flex wrap"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-for="(image, index) in uploadedImages"
|
v-for="(image, index) in [...uploadedImages, ...quoteList]"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="image-preview-item"
|
class="image-preview-item"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="image.url"
|
:src="image.url || image"
|
||||||
:alt="image.name"
|
|
||||||
class="preview-image"
|
class="preview-image"
|
||||||
@click="previewImage(image.url)"
|
@click="previewImage(image.url)"
|
||||||
/>
|
/>
|
||||||
@@ -211,7 +213,8 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="!isAgentMode"
|
v-if="!isAgentMode"
|
||||||
class="report-btn flex space-between align-center"
|
class="report-btn flex space-between align-center outer"
|
||||||
|
:class="{ 'is-cn': isCn }"
|
||||||
@click="toogltReportTag"
|
@click="toogltReportTag"
|
||||||
>
|
>
|
||||||
<SvgIcon class="light-icon" color="#FFDB56" name="light" size="16" />
|
<SvgIcon class="light-icon" color="#FFDB56" name="light" size="16" />
|
||||||
@@ -222,7 +225,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, watch, nextTick, onMounted } from 'vue'
|
import { computed, ref, watch, nextTick, onMounted, onUnmounted } from 'vue'
|
||||||
import { areaList } from '@/utils/area'
|
import { areaList } from '@/utils/area'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
@@ -254,11 +257,16 @@
|
|||||||
|
|
||||||
const emits = defineEmits(['send', 'pause'])
|
const emits = defineEmits(['send', 'pause'])
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t, locale } = useI18n()
|
||||||
|
|
||||||
|
const isCn = computed(() => {
|
||||||
|
return locale.value === 'CHINESE_SIMPLIFIED'
|
||||||
|
})
|
||||||
|
|
||||||
// 图片上传相关
|
// 图片上传相关
|
||||||
const fileInputRef = ref<HTMLInputElement | null>(null)
|
const fileInputRef = ref<HTMLInputElement | null>(null)
|
||||||
const uploadedImages = ref<Array<{ url: string; name: string }>>([])
|
const uploadedImages = ref<Array<{ url: string; name: string }>>([])
|
||||||
|
const quoteList = ref<Array<string>>([])
|
||||||
|
|
||||||
// 触发文件上传
|
// 触发文件上传
|
||||||
const triggerFileUpload = () => {
|
const triggerFileUpload = () => {
|
||||||
@@ -684,7 +692,8 @@
|
|||||||
const payload = {
|
const payload = {
|
||||||
text: inputValue.value.trim(),
|
text: inputValue.value.trim(),
|
||||||
images: imageUrlList,
|
images: imageUrlList,
|
||||||
tempImages: uploadedImages.value
|
tempImages: uploadedImages.value,
|
||||||
|
quoteList: quoteList.value
|
||||||
}
|
}
|
||||||
if (reportTags.value.length > 0) {
|
if (reportTags.value.length > 0) {
|
||||||
payload.useReport = true
|
payload.useReport = true
|
||||||
@@ -692,6 +701,7 @@
|
|||||||
emits('send', payload)
|
emits('send', payload)
|
||||||
// 发送后清空图片列表
|
// 发送后清空图片列表
|
||||||
uploadedImages.value = []
|
uploadedImages.value = []
|
||||||
|
quoteList.value = []
|
||||||
// 发送后清空输入框
|
// 发送后清空输入框
|
||||||
if (editorRef.value) {
|
if (editorRef.value) {
|
||||||
editorRef.value.innerHTML = ''
|
editorRef.value.innerHTML = ''
|
||||||
@@ -707,6 +717,7 @@
|
|||||||
|
|
||||||
// 初始化编辑器高度
|
// 初始化编辑器高度
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
MyEvent.add('quote', handleQuote)
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
autoResizeEditor()
|
autoResizeEditor()
|
||||||
})
|
})
|
||||||
@@ -803,6 +814,12 @@
|
|||||||
previewUrl.value = url
|
previewUrl.value = url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleQuote = (url: string) => {
|
||||||
|
quoteList.value.push(url)
|
||||||
|
}
|
||||||
|
onUnmounted(() => {
|
||||||
|
MyEvent.remove('quote', handleQuote)
|
||||||
|
})
|
||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
defineExpose({
|
defineExpose({
|
||||||
addReportTag
|
addReportTag
|
||||||
@@ -821,6 +838,10 @@
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1.1px solid #f6f4ef1a;
|
border: 1.1px solid #f6f4ef1a;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
&.outer.is-cn {
|
||||||
|
justify-content: center;
|
||||||
|
column-gap: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
.c-svg {
|
.c-svg {
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user