This commit is contained in:
liqiang-fit2cloud 2024-11-25 13:46:12 +08:00
commit 5974bd7986
31 changed files with 323 additions and 109 deletions

View File

@ -14,8 +14,8 @@ class BaseDocumentExtractNode(IDocumentExtractNode):
get_buffer = FileBufferHandle().get_buffer
self.context['document_list'] = document
content = ''
splitter = '\n-----------------------------------\n'
content = []
splitter = '\n`-----------------------------------`\n'
if document is None:
return NodeResult({'content': content}, {})
@ -29,10 +29,10 @@ class BaseDocumentExtractNode(IDocumentExtractNode):
# 回到文件头
buffer.seek(0)
file_content = split_handle.get_content(buffer)
content += splitter + '## ' + doc['name'] + '\n' + file_content
content.append( '## ' + doc['name'] + '\n' + file_content)
break
return NodeResult({'content': content}, {})
return NodeResult({'content': splitter.join(content)}, {})
def get_details(self, index: int, **kwargs):
return {

View File

@ -77,5 +77,6 @@ class BaseStartStepNode(IStarNode):
'status': self.status,
'err_message': self.err_message,
'image_list': self.context.get('image'),
'document_list': self.context.get('document'),
'global_fields': global_fields
}

View File

@ -38,7 +38,7 @@ from common.util.field_message import ErrMessage
from common.util.file_util import get_file_content
from common.util.lock import try_lock, un_lock
from dataset.models import Document, Problem, Paragraph, ProblemParagraphMapping
from dataset.serializers.common_serializers import get_embedding_model_id_by_dataset_id
from dataset.serializers.common_serializers import get_embedding_model_id_by_dataset_id, update_document_char_length
from dataset.serializers.paragraph_serializers import ParagraphSerializers
from embedding.task import embedding_by_paragraph, embedding_by_paragraph_list
from setting.models import Model
@ -620,6 +620,7 @@ class ChatRecordSerializer(serializers.Serializer):
# 插入关联问题
problem_paragraph_mapping.save()
chat_record.improve_paragraph_id_list.append(paragraph.id)
update_document_char_length(document_id)
# 添加标注
chat_record.save()
return ChatRecordSerializerModel(chat_record).data, paragraph.id, dataset_id
@ -718,5 +719,6 @@ class ChatRecordSerializer(serializers.Serializer):
# 批量保存聊天记录
ChatRecord.objects.bulk_update(chat_record_list, ['improve_paragraph_id_list'])
update_document_char_length(document_id)
return paragraph_ids, dataset_id

View File

@ -41,4 +41,4 @@ class CsvSplitHandle(BaseParseTableHandle):
return buffer.decode(detect(buffer)['encoding'])
except BaseException as e:
max_kb.error(f'csv split handle error: {e}')
return [{'name': file.name, 'paragraphs': []}]
return f'error: {e}'

View File

@ -63,21 +63,26 @@ class XlsSplitHandle(BaseParseTableHandle):
def get_content(self, file):
# 打开 .xls 文件
workbook = xlrd.open_workbook(file_contents=file.read(), formatting_info=True)
sheets = workbook.sheets()
md_tables = ''
for sheet in sheets:
try:
workbook = xlrd.open_workbook(file_contents=file.read(), formatting_info=True)
sheets = workbook.sheets()
md_tables = ''
for sheet in sheets:
# 获取表头和内容
headers = sheet.row_values(0)
data = [sheet.row_values(row_idx) for row_idx in range(1, sheet.nrows)]
# 获取表头和内容
headers = sheet.row_values(0)
data = [sheet.row_values(row_idx) for row_idx in range(1, sheet.nrows)]
# 构建 Markdown 表格
md_table = '| ' + ' | '.join(headers) + ' |\n'
md_table += '| ' + ' | '.join(['---'] * len(headers)) + ' |\n'
for row in data:
# 将每个单元格中的内容替换换行符为 <br> 以保留原始格式
md_table += '| ' + ' | '.join([str(cell).replace('\n', '<br>') if cell else '' for cell in row]) + ' |\n'
md_tables += md_table + '\n\n'
# 构建 Markdown 表格
md_table = '| ' + ' | '.join(headers) + ' |\n'
md_table += '| ' + ' | '.join(['---'] * len(headers)) + ' |\n'
for row in data:
# 将每个单元格中的内容替换换行符为 <br> 以保留原始格式
md_table += '| ' + ' | '.join(
[str(cell).replace('\n', '<br>') if cell else '' for cell in row]) + ' |\n'
md_tables += md_table + '\n\n'
return md_tables
return md_tables
except Exception as e:
max_kb.error(f'excel split handle error: {e}')
return f'error: {e}'

View File

@ -75,28 +75,32 @@ class XlsxSplitHandle(BaseParseTableHandle):
def get_content(self, file):
# 加载 Excel 文件
workbook = load_workbook(file)
md_tables = ''
# 如果未指定 sheet_name则使用第一个工作表
for sheetname in workbook.sheetnames:
sheet = workbook[sheetname] if sheetname else workbook.active
try:
# 加载 Excel 文件
workbook = load_workbook(file)
md_tables = ''
# 如果未指定 sheet_name则使用第一个工作表
for sheetname in workbook.sheetnames:
sheet = workbook[sheetname] if sheetname else workbook.active
# 获取工作表的所有行
rows = list(sheet.iter_rows(values_only=True))
if not rows:
continue
# 获取工作表的所有行
rows = list(sheet.iter_rows(values_only=True))
if not rows:
continue
# 提取表头和内容
headers = rows[0]
data = rows[1:]
# 提取表头和内容
headers = rows[0]
data = rows[1:]
# 构建 Markdown 表格
md_table = '| ' + ' | '.join(headers) + ' |\n'
md_table += '| ' + ' | '.join(['---'] * len(headers)) + ' |\n'
for row in data:
md_table += '| ' + ' | '.join(
[str(cell).replace('\n', '<br>') if cell is not None else '' for cell in row]) + ' |\n'
# 构建 Markdown 表格
md_table = '| ' + ' | '.join(headers) + ' |\n'
md_table += '| ' + ' | '.join(['---'] * len(headers)) + ' |\n'
for row in data:
md_table += '| ' + ' | '.join(
[str(cell).replace('\n', '<br>') if cell is not None else '' for cell in row]) + ' |\n'
md_tables += md_table + '\n\n'
return md_tables
md_tables += md_table + '\n\n'
return md_tables
except Exception as e:
max_kb.error(f'excel split handle error: {e}')
return f'error: {e}'

View File

@ -0,0 +1,4 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.77756 1.66699C4.28664 1.66699 3.88867 2.06496 3.88867 2.55588V19.4448C3.88867 19.9357 4.28664 20.3337 4.77756 20.3337H17.222C17.7129 20.3337 18.1109 19.9357 18.1109 19.4448V6.3069C18.1109 6.19036 18.0651 6.07847 17.9834 5.99536L13.8597 1.79989C13.7761 1.71488 13.6619 1.66699 13.5427 1.66699H4.77756ZM7.04915 9.02062C7.04915 8.77516 7.24814 8.57617 7.4936 8.57617H14.5059C14.7514 8.57617 14.9504 8.77516 14.9504 9.02062V9.74789C14.9504 9.99335 14.7514 10.1923 14.5059 10.1923H7.4936C7.24814 10.1923 7.04915 9.99335 7.04915 9.74789V9.02062ZM7.04915 13.061C7.04915 12.8156 7.24814 12.6166 7.4936 12.6166H10.5553C10.8008 12.6166 10.9998 12.8156 10.9998 13.061V13.7883C10.9998 14.0338 10.8008 14.2327 10.5553 14.2327H7.4936C7.24814 14.2327 7.04915 14.0338 7.04915 13.7883V13.061Z" fill="white"/>
<path opacity="0.5" d="M13.6665 1.68457C13.7391 1.70561 13.8058 1.74502 13.8597 1.7999L17.9835 5.99537C18.0172 6.02971 18.0449 6.06897 18.0657 6.11145H14.6755C14.1183 6.11145 13.6665 5.6597 13.6665 5.10244V1.68457Z" fill="#3370FF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,5 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.3335 3.33333C5.3335 2.59695 5.93045 2 6.66683 2H19.8146C19.9934 2 20.1647 2.07183 20.29 2.19934L26.4756 8.49255C26.5982 8.61722 26.6668 8.78505 26.6668 8.95987V28.6667C26.6668 29.403 26.0699 30 25.3335 30H6.66683C5.93045 30 5.3335 29.403 5.3335 28.6667V3.33333Z" fill="#3370FF"/>
<path d="M20 2.02637C20.1089 2.05793 20.2089 2.11704 20.2899 2.19936L26.4755 8.49256C26.5261 8.54408 26.5675 8.60297 26.5987 8.66668H21.5135C20.6776 8.66668 20 7.98906 20 7.15317V2.02637Z" fill="#2B5FD9"/>
<path d="M10.7636 13.5757H20.8727C20.9932 13.5757 21.0909 13.6734 21.0909 13.7939V14.8121C21.0909 14.9326 20.9932 15.0303 20.8727 15.0303H10.7636C10.6431 15.0303 10.5454 14.9326 10.5454 14.8121V13.7939C10.5454 13.6734 10.6431 13.5757 10.7636 13.5757ZM10.7636 17.9394H20.8727C20.9932 17.9394 21.0909 18.0371 21.0909 18.1576V19.1757C21.0909 19.2962 20.9932 19.3939 20.8727 19.3939H10.7636C10.6431 19.3939 10.5454 19.2962 10.5454 19.1757V18.1576C10.5454 18.0371 10.6431 17.9394 10.7636 17.9394ZM10.7636 22.303H16.1454C16.2659 22.303 16.3636 22.4007 16.3636 22.5212V23.5394C16.3636 23.6599 16.2659 23.7576 16.1454 23.7576H10.7636C10.6431 23.7576 10.5454 23.6599 10.5454 23.5394V22.5212C10.5454 22.4007 10.6431 22.303 10.7636 22.303Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,6 @@
<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 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="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 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>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.99967 2C1.63149 2 1.33301 2.29848 1.33301 2.66667V13.3333C1.33301 13.7015 1.63149 14 1.99967 14H13.9997C14.3679 14 14.6663 13.7015 14.6663 13.3333V2.66667C14.6663 2.29848 14.3679 2 13.9997 2H1.99967ZM13.333 3.33328V10.0001L11.9021 8.56907C11.7719 8.43893 11.5608 8.43893 11.4306 8.56907L9.56874 10.431C9.43854 10.5612 9.22747 10.5612 9.09727 10.431L5.56871 6.9024C5.43853 6.77227 5.22748 6.77227 5.09731 6.9024L2.66634 9.3334V3.33328H13.333Z" fill="white"/>
<path opacity="0.5" d="M10.333 5.33333C10.333 5.14924 10.4823 5 10.6663 5H11.6663C11.8504 5 11.9997 5.14924 11.9997 5.33333V6.33333C11.9997 6.51743 11.8504 6.66667 11.6663 6.66667H10.6663C10.4823 6.66667 10.333 6.51743 10.333 6.33333V5.33333Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 832 B

View File

@ -135,8 +135,7 @@
v-if="
item.type == WorkflowType.AiChat ||
item.type == WorkflowType.Question ||
item.type == WorkflowType.Application ||
item.type == WorkflowType.ImageUnderstandNode
item.type == WorkflowType.Application
"
>
<div
@ -175,7 +174,7 @@
</div>
<div class="card-never border-r-4 mt-8">
<h5 class="p-8-12">
{{ item.type == WorkflowType.Application ? '应用回答' : 'AI 回答' }}
{{ item.type == WorkflowType.Application ? '参数输出' : 'AI 回答' }}
</h5>
<div class="p-8-12 border-t-dashed lighter">
<MdPreview
@ -313,6 +312,103 @@
</div>
</div>
</template>
<!-- 表单收集 -->
<template v-if="item.type === WorkflowType.FormNode">
<div class="card-never border-r-4">
<h5 class="p-8-12">参数输入</h5>
<div class="p-8-12 border-t-dashed lighter">
<div v-for="(f, i) in item.form_field_list" :key="i" class="mb-8">
<span class="color-secondary">{{ f.label.label }}:</span>
{{ item.form_data[f.field] }}
</div>
</div>
</div>
</template>
<!-- 图片理解 -->
<template v-if="item.type == WorkflowType.ImageUnderstandNode">
<div
class="card-never border-r-4"
v-if="item.type !== WorkflowType.Application"
>
<h5 class="p-8-12">角色设定 (System)</h5>
<div class="p-8-12 border-t-dashed lighter">
{{ item.system || '-' }}
</div>
</div>
<div
class="card-never border-r-4 mt-8"
v-if="item.type !== WorkflowType.Application"
>
<h5 class="p-8-12">历史记录</h5>
<div class="p-8-12 border-t-dashed lighter">
<template v-if="item.history_message?.length > 0">
<p
class="mt-4 mb-4"
v-for="(history, historyIndex) in item.history_message"
:key="historyIndex"
>
<span class="color-secondary mr-4">{{ history.role }}:</span>
<span v-if="Array.isArray(history.content)">
<template v-for="(h, i) in history.content" :key="i">
<el-image
v-if="h.type === 'image_url'"
:src="h.image_url.url"
alt=""
fit="cover"
style="width: 40px; height: 40px; display: block"
class="border-r-4"
/>
<span v-else>{{ h.text }}</span>
</template>
</span>
<span v-else>{{ history.content }}</span>
</p>
</template>
<template v-else> - </template>
</div>
</div>
<div class="card-never border-r-4 mt-8">
<h5 class="p-8-12">本次对话</h5>
<div class="p-8-12 border-t-dashed lighter pre-wrap">
<div v-if="item.image_list?.length > 0">
<p class="mb-8 color-secondary">图片:</p>
<el-space wrap>
<template v-for="(f, i) in item.image_list" :key="i">
<el-image
:src="f.url"
alt=""
fit="cover"
style="width: 40px; height: 40px; display: block"
class="border-r-4"
/>
</template>
</el-space>
</div>
<div>
<p class="mb-8 color-secondary">提示词</p>
{{ item.question || '-' }}
</div>
</div>
</div>
<div class="card-never border-r-4 mt-8">
<h5 class="p-8-12">
{{ item.type == WorkflowType.Application ? '参数输出' : 'AI 回答' }}
</h5>
<div class="p-8-12 border-t-dashed lighter">
<MdPreview
v-if="item.answer"
ref="editorRef"
editorId="preview-only"
:modelValue="item.answer"
style="background: none"
/>
<template v-else> - </template>
</div>
</div>
</template>
</template>
<template v-else>
<div class="card-never border-r-4">

View File

@ -24,7 +24,7 @@
<el-icon><CircleCloseFilled /></el-icon>
</div>
<img :src="getImgUrl(item && item?.name)" alt="" width="24" />
<div class="ml-4 ellipsis" :title="item && item?.name">
<div class="ml-4 ellipsis" style="max-width: 160px" :title="item && item?.name">
{{ item && item?.name }}
</div>
</div>
@ -83,18 +83,29 @@
:accept="getAcceptList()"
:on-change="(file: any, fileList: any) => uploadFile(file, fileList)"
>
<el-button text>
<el-icon><Paperclip /></el-icon>
</el-button>
<el-tooltip effect="dark" placement="top" popper-class="upload-tooltip-width">
<template #content
>上传文件最多{{
props.applicationDetails.file_upload_setting.maxFiles
}}每个文件限制
{{ props.applicationDetails.file_upload_setting.fileLimit }}MB<br />文件类型{{
getAcceptList()
}}</template
>
<el-button text>
<el-icon><Paperclip /></el-icon>
</el-button>
</el-tooltip>
</el-upload>
<el-divider direction="vertical" />
</span>
<span v-if="props.applicationDetails.stt_model_enable" class="flex align-center">
<el-button text v-if="mediaRecorderStatus" @click="startRecording">
<el-button text @click="startRecording" v-if="mediaRecorderStatus">
<el-icon>
<Microphone />
</el-icon>
</el-button>
<div v-else class="operate flex align-center">
<el-text type="info"
>00:{{ recorderTime < 10 ? `0${recorderTime}` : recorderTime }}</el-text
@ -191,26 +202,30 @@ const audioExtensions = ['mp3', 'wav', 'aac', 'flac']
const getAcceptList = () => {
const { image, document, audio, video } = props.applicationDetails.file_upload_setting
let accepts = ''
let accepts: any = []
if (image) {
accepts += imageExtensions.map((ext) => '.' + ext).join(',')
accepts = [...imageExtensions]
}
if (document) {
accepts += documentExtensions.map((ext) => '.' + ext).join(',')
accepts = [...accepts, ...documentExtensions]
}
if (audio) {
accepts += audioExtensions.map((ext) => '.' + ext).join(',')
accepts = [...accepts, ...audioExtensions]
}
if (video) {
accepts += videoExtensions.map((ext) => '.' + ext).join(',')
accepts = [...accepts, ...videoExtensions]
}
return accepts
// console.log(accepts)
return accepts.map((ext: any) => '.' + ext).join(',')
}
const uploadFile = async (file: any, fileList: any) => {
const { maxFiles, fileLimit } = props.applicationDetails.file_upload_setting
if (fileList.length > maxFiles) {
//
const file_limit_once = uploadImageList.value.length + uploadDocumentList.value.length
if (file_limit_once >= maxFiles) {
MsgWarning('最多上传' + maxFiles + '个文件')
fileList.splice(0, fileList.length)
return
}
if (fileList.filter((f: any) => f.size > fileLimit * 1024 * 1024).length > 0) {
@ -454,4 +469,7 @@ onMounted(() => {
z-index: 1;
}
}
.upload-tooltip-width {
width: 300px;
}
</style>

View File

@ -18,10 +18,13 @@
<div class="mb-8" v-if="document_list.length">
<el-space wrap>
<template v-for="(item, index) in document_list" :key="index">
<el-card shadow="never" style="--el-card-padding: 8px" class="file cursor">
<div class="flex align-center">
<el-card shadow="never" style="--el-card-padding: 8px" class="download-file cursor">
<div class="download-button flex align-center" @click="downloadFile(item)">
<el-icon class="mr-4"><Download /></el-icon>
</div>
<div class="show flex align-center">
<img :src="getImgUrl(item && item?.name)" alt="" width="24" />
<div class="ml-4 ellipsis" :title="item && item?.name">
<div class="ml-4 ellipsis" style="max-width: 150px" :title="item && item?.name">
{{ item && item?.name }}
</div>
</div>
@ -55,7 +58,7 @@
</template>
<script setup lang="ts">
import { type chatType } from '@/api/type/application'
import { getImgUrl, getAttrsArray } from '@/utils/utils'
import { getImgUrl, getAttrsArray, downloadByURL } from '@/utils/utils'
import { onMounted, computed } from 'vue'
const props = defineProps<{
application: any
@ -80,13 +83,33 @@ const image_list = computed(() => {
}
})
onMounted(() => {
console.log(props.chatRecord.execution_details)
if (props.chatRecord.execution_details?.length > 0) {
props.chatRecord.execution_details[0].image_list?.forEach((image: any) => {
console.log('image', image.name, image.url)
})
}
})
function downloadFile(item: any) {
downloadByURL(item.url, item.name)
}
onMounted(() => {})
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.download-file {
width: 200px;
height: 43px;
&:hover {
color: var(--el-color-primary);
border: 1px solid var(--el-color-primary);
.download-button {
display: block;
text-align: center;
line-height: 26px;
}
.show {
display: none;
}
}
.show {
display: block;
}
.download-button {
display: none;
}
}
</style>

View File

@ -60,7 +60,7 @@ function checkboxChange() {
emit('change')
}
</script>
<style lang="scss" scoped>
<style lang="scss">
.card-checkbox {
&.active {
border: 1px solid var(--el-color-primary);

View File

@ -12,5 +12,6 @@ export enum modelType {
LLM = '大语言模型',
STT = '语音识别',
TTS = '语音合成',
IMAGE = '图片理解',
RERANKER = '重排模型'
}

View File

@ -88,3 +88,14 @@ export function getAttrsArray(array: Array<any>, attr: string) {
export function getSum(array: Array<any>) {
return array.reduce((total, item) => total + item, 0)
}
// 下载
export function downloadByURL(url: string, name: string) {
const a = document.createElement('a')
a.setAttribute('href', url)
a.setAttribute('target', '_blank')
a.setAttribute('download', name)
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}

View File

@ -198,6 +198,8 @@
:value-on-clear="0"
controls-position="right"
class="w-full"
:step="1"
:step-strictly="true"
/>
</el-form-item>
<el-form-item

View File

@ -79,9 +79,9 @@
/>
</template>
<template #subTitle>
<el-text class="lighter mr-8" size="small">
<el-text class="color-secondary" size="small">
<auto-tooltip :content="item.username">
创建: {{ item.username }}
创建: {{ item.username }}
</auto-tooltip>
</el-text>
</template>

View File

@ -48,12 +48,12 @@
$t('login.ldap.enableAuthentication')
}}</el-checkbox>
</el-form-item>
<el-button @click="submit(authFormRef, 'test')" :disabled="loading">
{{ $t('login.ldap.test') }}</el-button
>
</el-form>
<div class="text-right">
<el-button @click="submit(authFormRef, 'test')" :disabled="loading">
{{ $t('login.ldap.test') }}</el-button
>
<el-button @click="submit(authFormRef)" type="primary" :disabled="loading">
{{ $t('login.ldap.save') }}
</el-button>

View File

@ -82,7 +82,7 @@
</div>
</el-scrollbar>
<div>
<el-checkbox v-model="checkedConnect" @change="changeHandle">
<el-checkbox v-model="checkedConnect" @change="changeHandle" style="white-space: normal;">
导入时添加分段标题为关联问题适用于标题为问题的问答对
</el-checkbox>
</div>

View File

@ -62,9 +62,9 @@
</AppAvatar>
</template>
<template #subTitle>
<el-text class="lighter mr-8" size="small">
<el-text class="color-secondary" size="small">
<auto-tooltip :content="item.username">
创建: {{ item.username }}
创建: {{ item.username }}
</auto-tooltip>
</el-text>
</template>

View File

@ -67,9 +67,9 @@
</AppAvatar>
</template>
<template #subTitle>
<el-text class="lighter mr-8" size="small">
<el-text class="color-secondary" size="small">
<auto-tooltip :content="item.username">
创建: {{ item.username }}
创建: {{ item.username }}
</auto-tooltip>
</el-text>
</template>

View File

@ -221,7 +221,7 @@ export const imageUnderstandNode = {
fields: [
{
label: 'AI 回答内容',
value: 'content'
value: 'answer'
}
]
}

View File

@ -71,7 +71,11 @@ class CustomEdge2 extends BezierEdge {
delete style.stroke
return h('g', {}, [
h('style', { type: 'text/css' }, '.lf-edge{stroke:#afafaf}.lf-edge:hover{stroke: #3370FF;}'),
h(
'style' as any,
{ type: 'text/css' },
'.lf-edge{stroke:#afafaf}.lf-edge:hover{stroke: #3370FF;}'
),
h('path', {
d: path,
...style,

View File

@ -1,6 +1,6 @@
<template>
<AppAvatar shape="square" style="background: #7F3BF5">
<img src="@/assets/icon_document.svg" style="width: 65%" alt="" />
<AppAvatar shape="square" class="avatar-blue">
<img src="@/assets/icon_docs.svg" style="width: 65%" alt="" />
</AppAvatar>
</template>
<script setup lang="ts"></script>

View File

@ -1,6 +1,6 @@
<template>
<AppAvatar shape="square" style="background: #14C0FF;">
<img src="@/assets/icon_document.svg" style="width: 65%" alt="" />
<img src="@/assets/icon_image.svg" style="width: 65%" alt="" />
</AppAvatar>
</template>
<script setup lang="ts"></script>

View File

@ -154,6 +154,8 @@
:value-on-clear="0"
controls-position="right"
class="w-full"
:step="1"
:step-strictly="true"
/>
</el-form-item>
<el-form-item label="返回内容" @click.prevent>

View File

@ -7,34 +7,64 @@
:destroy-on-close="true"
:before-close="close"
append-to-body
width="600"
>
<el-form
label-position="top"
ref="fieldFormRef"
:model="form_data"
require-asterisk-position="right">
require-asterisk-position="right"
>
<el-form-item label="单次上传最多文件数">
<el-slider v-model="form_data.maxFiles" show-input :show-input-controls="false" :min="1" :max="10" />
<el-slider
v-model="form_data.maxFiles"
show-input
:show-input-controls="false"
:min="1"
:max="10"
/>
</el-form-item>
<el-form-item label="每个文件最大MB">
<el-slider v-model="form_data.fileLimit" show-input :show-input-controls="false" :min="1" :max="100" />
<el-slider
v-model="form_data.fileLimit"
show-input
:show-input-controls="false"
:min="1"
:max="100"
/>
</el-form-item>
<el-form-item label="上传的文件类型">
<el-card style="width: 100%" class="mb-8">
<el-card
shadow="hover"
class="card-checkbox cursor w-full mb-8"
:class="form_data.document ? 'active' : ''"
style="--el-card-padding: 8px 16px"
>
<div class="flex-between">
<p>
文档TXTMDDOCXHTMLCSVXLSXXLSPDF
需要与文档内容提取节点配合使用
</p>
<div class="flex align-center">
<img class="mr-12" src="@/assets/icon_file-doc.svg" alt="" />
<div>
<p>文档TXTMDDOCXHTMLCSVXLSXXLSPDF</p>
<el-text class="color-secondary">需要与文档内容提取节点配合使用</el-text>
</div>
</div>
<el-checkbox v-model="form_data.document" />
</div>
</el-card>
<el-card style="width: 100%" class="mb-8">
<el-card
shadow="hover"
class="card-checkbox cursor w-full mb-8"
:class="form_data.image ? 'active' : ''"
style="--el-card-padding: 8px 16px"
>
<div class="flex-between">
<p>
图片JPGJPEGPNGGIF
所选模型需要支持接收图片
</p>
<div class="flex align-center">
<img class="mr-12" src="@/assets/icon_file-image.svg" alt="" />
<div>
<p>图片JPGJPEGPNGGIF</p>
<el-text class="color-secondary">所选模型需要支持接收图片</el-text>
</div>
</div>
<el-checkbox v-model="form_data.image" />
</div>
</el-card>
@ -43,9 +73,7 @@
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="close"> 取消 </el-button>
<el-button type="primary" @click="submit()" :loading="loading">
确定
</el-button>
<el-button type="primary" @click="submit()" :loading="loading"> 确定 </el-button>
</span>
</template>
</el-dialog>
@ -69,7 +97,6 @@ const form_data = ref({
video: false
})
function open(data: any) {
dialogVisible.value = true
nextTick(() => {
@ -96,6 +123,4 @@ defineExpose({
})
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>

View File

@ -22,7 +22,7 @@
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择文档"
v-model="form.document_list"
v-model="form_data.document_list"
/>
</el-form-item>
</el-form>

View File

@ -7,7 +7,6 @@
:model="form_data"
label-position="top"
require-asterisk-position="right"
class="mb-24"
label-width="auto"
ref="aiChatNodeFormRef"
hide-required-asterisk
@ -132,7 +131,7 @@
<template #label>
<div class="flex-between">
<div>历史聊天记录</div>
<el-select v-model="form_data.dialogue_type" class="w-120">
<el-select v-model="form_data.dialogue_type" type="small" style="width: 100px;">
<el-option label="节点" value="NODE"/>
<el-option label="工作流" value="WORKFLOW"/>
</el-select>

View File

@ -152,6 +152,8 @@
:value-on-clear="0"
controls-position="right"
class="w-full"
:step="1"
:step-strictly="true"
/>
</el-form-item>
<el-form-item label="返回内容" @click.prevent>