|
|
|
@ -4,7 +4,6 @@ import {Local} from "@/utils/storage/storage";
|
|
|
|
|
import dayjs from "dayjs";
|
|
|
|
|
import {computed, onMounted, onUnmounted, ref, watch} from 'vue'
|
|
|
|
|
import {useRoute} from 'vue-router'
|
|
|
|
|
import {NAutoComplete, NButton, NInput, useDialog, useMessage, NBackTop,NIcon} from 'naive-ui'
|
|
|
|
|
import {AreaChartOutlined, PlusOutlined} from '@ant-design/icons-vue';
|
|
|
|
|
import html2canvas from 'html2canvas'
|
|
|
|
|
import {Message} from './components'
|
|
|
|
@ -99,21 +98,19 @@ const API_URL = `${import.meta.env.VITE_APP_API_BASE_URL}/chat/completion`;
|
|
|
|
|
const createParams = () => {
|
|
|
|
|
const messages = dataSources.value.map((x) => {
|
|
|
|
|
return {
|
|
|
|
|
content: (() => {
|
|
|
|
|
if (gptMode.value === 'gpt-4-vision-preview') {
|
|
|
|
|
return [{
|
|
|
|
|
type: "text",
|
|
|
|
|
text: x.text
|
|
|
|
|
}, ...x.fileList.map((y) => {
|
|
|
|
|
return {
|
|
|
|
|
type: "image_url",
|
|
|
|
|
image_url: y
|
|
|
|
|
}
|
|
|
|
|
})]
|
|
|
|
|
} else {
|
|
|
|
|
return x.text
|
|
|
|
|
}
|
|
|
|
|
})(),
|
|
|
|
|
content: (() => {
|
|
|
|
|
if (gptMode.value === 'gpt-4-vision-preview') {
|
|
|
|
|
return [{
|
|
|
|
|
type: "text",
|
|
|
|
|
text: x.text
|
|
|
|
|
}, ...(Array.isArray(x.fileList) && x.fileList.length > 0 ? x.fileList.map(y => ({
|
|
|
|
|
type: "image_url",
|
|
|
|
|
image_url: y
|
|
|
|
|
})) : [])]
|
|
|
|
|
} else {
|
|
|
|
|
return x.text
|
|
|
|
|
}
|
|
|
|
|
})(),
|
|
|
|
|
role: x.inversion ? 'user' : 'assistant'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
@ -389,17 +386,13 @@ const handleCancel = () => {
|
|
|
|
|
previewTitle.value = '';
|
|
|
|
|
};
|
|
|
|
|
const handlePreview = async (file) => {
|
|
|
|
|
if (!file.url && !file.preview) {
|
|
|
|
|
file.preview = (await getBase64(file.originFileObj))
|
|
|
|
|
}
|
|
|
|
|
previewImage.value = file.url || file.preview;
|
|
|
|
|
previewVisible.value = true;
|
|
|
|
|
previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1);
|
|
|
|
|
previewImage.value = (await getBase64(file.file));
|
|
|
|
|
previewVisible.value = true;
|
|
|
|
|
};
|
|
|
|
|
const value = ref('gpt-3.5-turbo');
|
|
|
|
|
const visible = ref(false)
|
|
|
|
|
const removeImg = (data) => {
|
|
|
|
|
fileList.value.splice(fileList.value.findIndex(x => x.url === data.url), 1)
|
|
|
|
|
fileList.value.splice(fileList.value.findIndex(x => x.id === data.file.id), 1)
|
|
|
|
|
}
|
|
|
|
|
watch(gptMode, () => {
|
|
|
|
|
currentListUuid.value = ''
|
|
|
|
@ -410,11 +403,11 @@ const fileList1 = ref([])
|
|
|
|
|
const isFile = ref(false)
|
|
|
|
|
const upItemImage1 = async (file) => {
|
|
|
|
|
const data = {
|
|
|
|
|
file: file.file,
|
|
|
|
|
file: file.file.file,
|
|
|
|
|
}
|
|
|
|
|
const res = await uploadFormData(data)
|
|
|
|
|
if (res.code === 0) {
|
|
|
|
|
file.onSuccess()
|
|
|
|
|
file.onFinish()
|
|
|
|
|
dataSources.value = [...dataSources.value, ...res.data.paragraph.flatMap(n => [n, '']).map((x) => {
|
|
|
|
|
return {
|
|
|
|
|
dateTime: dayjs().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
@ -434,14 +427,17 @@ watch(dataSources,()=>{
|
|
|
|
|
scrollToBottom('auto')
|
|
|
|
|
})
|
|
|
|
|
const customRequest = async (file) => {
|
|
|
|
|
console.log(file,'file')
|
|
|
|
|
const res = await uploadImg({
|
|
|
|
|
file: file.file,
|
|
|
|
|
file: file.file.file,
|
|
|
|
|
source: 'approval'
|
|
|
|
|
})
|
|
|
|
|
if (res.code === 0) {
|
|
|
|
|
file.onSuccess()
|
|
|
|
|
fileList.value.push({
|
|
|
|
|
url: res.data.ori_url
|
|
|
|
|
file.onFinish()
|
|
|
|
|
fileList.value.push({
|
|
|
|
|
id:file.file.id,
|
|
|
|
|
url: res.data.ori_url,
|
|
|
|
|
status: 'finished',
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -516,31 +512,48 @@ const customRequest = async (file) => {
|
|
|
|
|
<footer :class="footerClass">
|
|
|
|
|
<div class="w-full max-w-screen-xl m-auto">
|
|
|
|
|
<div class="flex items-center justify-center space-x-2" style="flex-wrap: initial">
|
|
|
|
|
<a-popover :open="visible1" trigger="click">
|
|
|
|
|
<template #content>
|
|
|
|
|
<div class="clearfix">
|
|
|
|
|
<a-upload
|
|
|
|
|
:max-count="1"
|
|
|
|
|
v-model:file-list="fileList1"
|
|
|
|
|
name="file"
|
|
|
|
|
:customRequest="upItemImage1"
|
|
|
|
|
>
|
|
|
|
|
<a-button>
|
|
|
|
|
<upload-outlined></upload-outlined>
|
|
|
|
|
上传文件
|
|
|
|
|
</a-button>
|
|
|
|
|
</a-upload>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<HoverButton @click="visible1=!visible1">
|
|
|
|
|
<NPopover trigger="click" :show="visible1">
|
|
|
|
|
<template #trigger>
|
|
|
|
|
<HoverButton @click="visible1=!visible1">
|
|
|
|
|
<span class="text-xl text-[#4f555e] dark:text-white"
|
|
|
|
|
style="display: flex;justify-content: center;align-items: center"
|
|
|
|
|
>
|
|
|
|
|
style="display: flex;justify-content: center;align-items: center"
|
|
|
|
|
>
|
|
|
|
|
<SvgIcon icon="ri:upload-2-line"/>
|
|
|
|
|
</span>
|
|
|
|
|
</HoverButton>
|
|
|
|
|
</a-popover>
|
|
|
|
|
<a-popover v-if="gptMode==='gpt-4-vision-preview'" :open="visible" trigger="click">
|
|
|
|
|
</HoverButton>
|
|
|
|
|
</template>
|
|
|
|
|
<div class="clearfix">
|
|
|
|
|
<NUpload
|
|
|
|
|
:max-count="1"
|
|
|
|
|
:default-file-list="fileList1"
|
|
|
|
|
name="file"
|
|
|
|
|
:customRequest="upItemImage1"
|
|
|
|
|
>
|
|
|
|
|
<NButton >上传文件</NButton>
|
|
|
|
|
</NUpload>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</NPopover>
|
|
|
|
|
<NPopover v-if="gptMode==='gpt-4-vision-preview'" :show="visible" trigger="click">
|
|
|
|
|
<template #trigger>
|
|
|
|
|
<HoverButton @click="visible=!visible">
|
|
|
|
|
<span class="text-xl text-[#4f555e] dark:text-white"
|
|
|
|
|
style="display: flex;justify-content: center;align-items: center"
|
|
|
|
|
>
|
|
|
|
|
<AreaChartOutlined/>
|
|
|
|
|
</span>
|
|
|
|
|
</HoverButton>
|
|
|
|
|
</template>
|
|
|
|
|
<NUpload
|
|
|
|
|
:file-list-style="{display:'flex'}"
|
|
|
|
|
:custom-request="customRequest"
|
|
|
|
|
:default-file-list="fileList"
|
|
|
|
|
list-type="image-card"
|
|
|
|
|
:on-preview="handlePreview"
|
|
|
|
|
:on-remove="removeImg"
|
|
|
|
|
/>
|
|
|
|
|
</NPopover>
|
|
|
|
|
<!-- <a-popover v-if="gptMode==='gpt-4-vision-preview'" :open="visible" trigger="click">
|
|
|
|
|
<template #content>
|
|
|
|
|
<div class="clearfix">
|
|
|
|
|
<a-upload
|
|
|
|
@ -567,7 +580,7 @@ const customRequest = async (file) => {
|
|
|
|
|
<AreaChartOutlined/>
|
|
|
|
|
</span>
|
|
|
|
|
</HoverButton>
|
|
|
|
|
</a-popover>
|
|
|
|
|
</a-popover>-->
|
|
|
|
|
<!-- <HoverButton v-if="!isMobile" @click="handleClear">
|
|
|
|
|
<span class="text-xl text-[#4f555e] dark:text-white">
|
|
|
|
|
<SvgIcon icon="ri:delete-bin-line" />
|
|
|
|
@ -602,6 +615,7 @@ const customRequest = async (file) => {
|
|
|
|
|
@blur="handleBlur"
|
|
|
|
|
@keypress="handleEnter"
|
|
|
|
|
/> -->
|
|
|
|
|
|
|
|
|
|
<NInput
|
|
|
|
|
style="width:75%"
|
|
|
|
|
ref="inputRef"
|
|
|
|
@ -627,6 +641,13 @@ const customRequest = async (file) => {
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</footer>
|
|
|
|
|
<NModal
|
|
|
|
|
v-model:show="previewVisible"
|
|
|
|
|
preset="card"
|
|
|
|
|
style="width: 600px"
|
|
|
|
|
>
|
|
|
|
|
<img :src="previewImage" style="width: 100%">
|
|
|
|
|
</NModal>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<style scoped>
|
|
|
|
|