This commit is contained in:
liqiang-fit2cloud 2025-02-28 12:28:40 +08:00
commit 2abf05f11a
37 changed files with 422 additions and 170 deletions

View File

@ -40,7 +40,6 @@ splitter = '\n`-----------------------------------`\n'
class BaseDocumentExtractNode(IDocumentExtractNode):
def save_context(self, details, workflow_manage):
self.context['content'] = details.get('content')
self.answer_text = details.get('content')
def execute(self, document, chat_id, **kwargs):

View File

@ -66,7 +66,7 @@ class ISearchDatasetStepNode(INode):
if self.flow_params_serializer.data.get('re_chat', False):
history_chat_record = self.flow_params_serializer.data.get('history_chat_record', [])
paragraph_id_list = [p.get('id') for p in flat_map(
[get_paragraph_list(chat_record, self.node.id) for chat_record in history_chat_record if
[get_paragraph_list(chat_record, self.runtime_node_id) for chat_record in history_chat_record if
chat_record.problem_text == question])]
exclude_paragraph_id_list = list(set(paragraph_id_list))

View File

@ -6761,3 +6761,6 @@ msgstr ""
msgid "AI reply: "
msgstr ""
msgid "The network is busy, try again later."
msgstr ""

View File

@ -6900,3 +6900,6 @@ msgstr "思考过程: "
msgid "AI reply: "
msgstr "AI 回复: "
msgid "The network is busy, try again later."
msgstr "网络繁忙,请稍后再试。"

View File

@ -6911,4 +6911,7 @@ msgid "Think: "
msgstr "思考過程: "
msgid "AI reply: "
msgstr "AI 回覆: "
msgstr "AI 回覆: "
msgid "The network is busy, try again later."
msgstr "網絡繁忙,請稍後再試。"

View File

@ -122,7 +122,7 @@ function showSource(row: any) {
return false
}
const regenerationChart = (chat: chatType) => {
props.sendMessage(chat.problem_text, { rechat: true })
props.sendMessage(chat.problem_text, { re_chat: true })
}
const stopChat = (chat: chatType) => {
props.chatManagement.stop(chat.id)

View File

@ -86,6 +86,7 @@ import applicationApi from '@/api/application'
import { datetimeFormat } from '@/utils/time'
import { MsgError } from '@/utils/message'
import { t } from '@/locales'
import bus from '@/bus'
const route = useRoute()
const {
params: { id }
@ -277,6 +278,11 @@ const pausePlayAnswerText = () => {
}
onMounted(() => {
bus.on('pause-autoplay', () => {
pausePlayAnswerText()
// console.log(1234)
})
bus.emit('pause-autoplay')
//
if (props.tts && props.tts_autoplay && buttonData.value.write_ed && !buttonData.value.update_time) {
playAnswerText(buttonData.value.answer_text)

View File

@ -16,7 +16,9 @@
<el-icon class="mr-8 arrow-icon" :class="showUserInput ? 'rotate-90' : ''"
><CaretRight
/></el-icon>
<span class="break-all ellipsis-1 mr-16" :title="inputFieldConfig.title">
{{ inputFieldConfig.title }}
</span>
</div>
<el-scrollbar max-height="160">
<el-collapse-transition>

View File

@ -4,6 +4,10 @@ const input_type_list = [
label: t('dynamicsForm.input_type_list.TextInput'),
value: 'TextInput'
},
{
label: t('dynamicsForm.input_type_list.PasswordInput'),
value: 'PasswordInput'
},
{
label: t('dynamicsForm.input_type_list.Slider'),
value: 'Slider'

View File

@ -0,0 +1,194 @@
<template>
<el-form-item :label="$t('dynamicsForm.TextInput.length.label')" required>
<el-row class="w-full">
<el-col :span="11">
<el-form-item
:rules="[
{
required: true,
message: $t('dynamicsForm.TextInput.length.minRequired'),
trigger: 'change'
}
]"
prop="minlength"
>
<el-input-number
style="width: 100%"
:min="1"
:step="1"
step-strictly
v-model="formValue.minlength"
controls-position="right"
/>
</el-form-item>
</el-col>
<el-col :span="2" class="text-center">
<span>-</span>
</el-col>
<el-col :span="11">
<el-form-item
:rules="[
{
required: true,
message: $t('dynamicsForm.TextInput.length.maxRequired'),
trigger: 'change'
}
]"
prop="maxlength"
>
<el-input-number
style="width: 100%"
:min="formValue.minlength > formValue.maxlength ? formValue.minlength : 1"
step-strictly
:step="1"
v-model="formValue.maxlength"
controls-position="right"
/>
</el-form-item>
</el-col>
</el-row>
</el-form-item>
<el-form-item
class="defaultValueItem"
:required="formValue.required"
prop="default_value"
:label="$t('dynamicsForm.default.label')"
:rules="
formValue.required ? [{ required: true, message: `${$t('dynamicsForm.default.label')}${$t('dynamicsForm.default.requiredMessage')}` }, ...rules] : rules
"
>
<div class="defaultValueCheckbox">
<el-checkbox
v-model="formValue.show_default_value"
:label="$t('dynamicsForm.default.show')"
/>
</div>
<el-input
v-model="formValue.default_value"
:maxlength="formValue.maxlength"
:minlength="formValue.minlength"
:placeholder="$t('dynamicsForm.default.placeholder')"
show-word-limit
type="password"
show-password
/>
</el-form-item>
</template>
<script setup lang="ts">
import { computed, onMounted, watch } from 'vue'
import { t } from '@/locales'
const props = defineProps<{
modelValue: any
}>()
const emit = defineEmits(['update:modelValue'])
const formValue = computed({
set: (item) => {
emit('update:modelValue', item)
},
get: () => {
return props.modelValue
}
})
watch(
() => formValue.value.minlength,
() => {
if (formValue.value.minlength > formValue.value.maxlength) {
formValue.value.maxlength = formValue.value.minlength
}
}
)
const getData = () => {
return {
input_type: 'PasswordInput',
attrs: {
maxlength: formValue.value.maxlength,
minlength: formValue.value.minlength,
'show-word-limit': true,
type: 'password',
'show-password': true
},
default_value: formValue.value.default_value,
show_default_value: formValue.value.show_default_value,
props_info: {
rules: formValue.value.required
? [
{
required: true,
message: `${formValue.value.label} ${t('dynamicsForm.default.requiredMessage')}`
},
{
min: formValue.value.minlength,
max: formValue.value.maxlength,
message: `${formValue.value.label}${t('dynamicsForm.TextInput.length.requiredMessage1')} ${formValue.value.minlength} ${t('dynamicsForm.TextInput.length.requiredMessage2')} ${formValue.value.maxlength} ${t('dynamicsForm.TextInput.length.requiredMessage3')}`,
trigger: 'blur'
}
]
: [
{
min: formValue.value.minlength,
max: formValue.value.maxlength,
message: `${formValue.value.label}${t('dynamicsForm.TextInput.length.requiredMessage1')} ${formValue.value.minlength} ${t('dynamicsForm.TextInput.length.requiredMessage2')} ${formValue.value.maxlength} ${t('dynamicsForm.TextInput.length.requiredMessage3')}`,
trigger: 'blur'
}
]
}
}
}
const rander = (form_data: any) => {
const attrs = form_data.attrs || {}
formValue.value.minlength = attrs.minlength
formValue.value.maxlength = attrs.maxlength
formValue.value.default_value = form_data.default_value
formValue.value.show_default_value = form_data.show_default_value
formValue.value.show_password = attrs['show-password']
}
const rangeRules = [
{
required: true,
validator: (rule: any, value: any, callback: any) => {
if (!formValue.value.minlength) {
callback(new Error(t('dynamicsForm.TextInput.length.requiredMessage4')))
}
if (!formValue.value.maxlength) {
callback(new Error(t('dynamicsForm.TextInput.length.requiredMessage4')))
}
return true
},
message: `${formValue.value.label} ${t('dynamicsForm.default.requiredMessage')}`
}
]
const rules = computed(() => [
{
min: formValue.value.minlength,
max: formValue.value.maxlength,
message: `${t('dynamicsForm.TextInput.length.requiredMessage1')} ${formValue.value.minlength} ${t('dynamicsForm.TextInput.length.requiredMessage2')} ${formValue.value.maxlength} ${t('dynamicsForm.TextInput.length.requiredMessage3')}`,
trigger: 'blur'
}
])
defineExpose({ getData, rander })
onMounted(() => {
formValue.value.minlength = 0
formValue.value.maxlength = 20
formValue.value.default_value = ''
formValue.value.show_password = true
if (formValue.value.show_default_value === undefined) {
formValue.value.show_default_value = true
}
})
</script>
<style lang="scss" scoped>
.defaultValueItem {
position: relative;
.defaultValueCheckbox {
position: absolute;
right: 0;
top: -35px;
}
}
</style>

View File

@ -1,11 +1,4 @@
<template>
<el-form-item
class="defaultValueItem"
prop="show_password"
:label="$t('dynamicsForm.TextInput.showPassword')"
>
<el-switch v-model="formValue.show_password" />
</el-form-item>
<el-form-item :label="$t('dynamicsForm.TextInput.length.label')" required>
<el-row class="w-full">
<el-col :span="11">
@ -77,8 +70,7 @@
:minlength="formValue.minlength"
:placeholder="$t('dynamicsForm.default.placeholder')"
show-word-limit
:type="formValue.show_password ? 'password' : 'text'"
:show-password="formValue.show_password"
type="text"
/>
</el-form-item>
</template>
@ -111,9 +103,7 @@ const getData = () => {
attrs: {
maxlength: formValue.value.maxlength,
minlength: formValue.value.minlength,
'show-word-limit': true,
type: formValue.value.show_password ? 'password' : 'text',
'show-password': formValue.value.show_password
'show-word-limit': true
},
default_value: formValue.value.default_value,
show_default_value: formValue.value.show_default_value,
@ -145,7 +135,6 @@ const rander = (form_data: any) => {
formValue.value.maxlength = attrs.maxlength
formValue.value.default_value = form_data.default_value
formValue.value.show_default_value = form_data.show_default_value
formValue.value.show_password = attrs['show-password']
}
const rangeRules = [
{
@ -176,8 +165,7 @@ onMounted(() => {
formValue.value.minlength = 0
formValue.value.maxlength = 20
formValue.value.default_value = ''
formValue.value.show_password = false
// console.log(formValue.value.show_default_value)
if (formValue.value.show_default_value === undefined) {
formValue.value.show_default_value = true
}

View File

@ -48,13 +48,13 @@
type="textarea"
/>
</el-form-item>
<el-form-item :label="$t('views.problem.relateParagraph.selectParagraph')" prop="state">
<el-form-item v-if="apiType === 'document'" :label="$t('components.selectParagraph.title')" prop="state">
<el-radio-group v-model="state" class="radio-block">
<el-radio value="error" size="large" class="mb-16">{{
$t('views.document.form.selectVectorization.error')
<el-radio value="error" size="large">{{
$t('components.selectParagraph.error')
}}</el-radio>
<el-radio value="all" size="large">{{
$t('views.document.form.selectVectorization.all')
$t('components.selectParagraph.all')
}}</el-radio>
</el-radio-group>
</el-form-item>
@ -148,7 +148,6 @@ const submitHandle = async (formEl: FormInstance) => {
const data = {
...form.value,
paragraph_id_list: idList.value,
state_list: stateMap[state.value]
}
paragraphApi.batchGenerateRelated(id, documentId, data, loading).then(() => {
MsgSuccess(t('views.document.generateQuestion.successMessage'))

View File

@ -57,5 +57,6 @@ export default {
inputPlaceholder: 'Please input',
title: 'Title',
content: 'Content'
content: 'Content',
rename: 'Rename'
}

View File

@ -3,5 +3,10 @@ export default {
quickCreateName: 'document name',
noData: 'No Data',
loading: 'Loading',
noMore: 'No more'
noMore: 'No more! ',
selectParagraph: {
title: 'Select Paragraph',
error: 'Process only the failed segments',
all: 'All Segments'
}
}

View File

@ -1,6 +1,7 @@
export default {
input_type_list: {
TextInput: 'Input',
PasswordInput: 'Password',
Slider: 'Slider',
SwitchInput: 'Switch',
SingleSelect: 'Single Select',
@ -96,7 +97,6 @@ export default {
requiredMessage2: 'and',
requiredMessage3: 'characters',
requiredMessage4: 'Text length is a required parameter'
},
showPassword: 'Show Password'
}
}
}

View File

@ -1,5 +1,6 @@
export default {
node: 'Node',
nodeName: 'Node Name',
baseComponent: 'Basic',
nodeSetting: 'Node Settings',
workflow: 'Workflow',

View File

@ -12,7 +12,7 @@ export default {
cancelGenerateQuestion: 'Cancel Generating Questions',
cancelVectorization: 'Cancel Vectorization',
cancelGenerate: 'Cancel Generation',
export: 'Export to',
export: 'Export to'
},
tip: {
saveMessage: 'Current changes have not been saved. Confirm exit?',
@ -84,8 +84,7 @@ export default {
text: 'Remove duplicate extra symbols, spaces, blank lines, and tab words.'
},
checkedConnect: {
label:
'Add "Related Questions" section for question-based QA pairs during import.'
label: 'Add "Related Questions" section for question-based QA pairs during import.'
}
},
buttons: {
@ -153,11 +152,6 @@ export default {
label: 'Similarity Higher Than',
placeholder: 'Directly return segment content',
requiredMessage: 'Please enter similarity value'
},
selectVectorization: {
label: 'Select Vectorization Content',
error: 'Segments that failed vectorization',
all: 'All Segments'
}
},
hitHandlingMethod: {
@ -173,7 +167,6 @@ export default {
tip4: 'The generation effect depends on the selected model and prompt. Users can adjust to achieve the best effect.',
prompt1:
'Content: {data}\n \n Please summarize the above and generate 5 questions based on the summary. \nAnswer requirements: \n - Please output only questions; \n - Please place each question in',
prompt2: 'tag.',
error: 'Segments only failed',
prompt2: 'tag.'
}
}

View File

@ -31,7 +31,6 @@ export default {
title: 'Relate to Segment',
selectDocument: 'Select a Document',
placeholder: 'Search document by name',
selectParagraph: 'Select Segments',
selectedParagraph: 'Selected Segments',
count: 'Count'
}

View File

@ -56,5 +56,6 @@ export default {
param: {
outputParam: '输出参数',
inputParam:'输入参数'
}
},
rename:'重命名'
}

View File

@ -4,4 +4,9 @@ export default {
noData: '无匹配数据',
loading: '加载中',
noMore: '到底啦!',
selectParagraph: {
title: '选择分段',
error: '仅执行未成功分段',
all: '全部分段'
}
}

View File

@ -1,6 +1,7 @@
export default {
input_type_list: {
TextInput: '文本框',
PasswordInput: '密码框',
Slider: '滑块',
SwitchInput: '开关',
SingleSelect: '单选框',
@ -96,7 +97,6 @@ export default {
requiredMessage2: '到',
requiredMessage3: '个字符',
requiredMessage4: '文本长度为必填参数'
},
showPassword: '密文显示'
}
}
}

View File

@ -1,5 +1,6 @@
export default {
node: '节点',
nodeName: '节点名称',
baseComponent: '基础组件',
nodeSetting: '节点设置',
workflow: '工作流',

View File

@ -150,11 +150,6 @@ export default {
placeholder: '直接返回分段内容',
requiredMessage: '请输入相似度'
},
selectVectorization: {
label: '选择向量化内容',
error: '向量化未成功的分段',
all: '全部分段'
}
},
hitHandlingMethod: {
optimization: '模型优化',
@ -169,6 +164,5 @@ export default {
tip4: '生成效果依赖于所选模型和提示词,用户可自行调整至最佳效果。',
prompt1: `内容:{data}\n\n请总结上面的内容并根据内容总结生成 5 个问题。\n回答要求\n- 请只输出问题;\n- 请将每个问题放置`,
prompt2: `标签中。`,
error: '仅执行未成功的分段',
}
}

View File

@ -31,7 +31,6 @@ export default {
title: '关联分段',
selectDocument: '选择文档',
placeholder: '按 文档名称 搜索',
selectParagraph: '选择分段',
selectedParagraph: '已选分段',
count: '个'
},

View File

@ -55,6 +55,7 @@ export default {
content: '内容',
param: {
outputParam: '輸出參數',
inputParam:'輸入參數'
}
inputParam: '輸入參數'
},
rename: '重命名'
}

View File

@ -4,4 +4,9 @@ export default {
noData: '無匹配数据',
loading: '加載中',
noMore: '到底啦!',
selectParagraph: {
title: '選擇分段',
error: '僅執行未成功分段',
all: '全部分段'
}
}

View File

@ -1,6 +1,7 @@
export default {
input_type_list: {
TextInput: '文字框',
PasswordInput: '密文框',
Slider: '滑桿',
SwitchInput: '開關',
SingleSelect: '單選框',
@ -96,7 +97,6 @@ export default {
requiredMessage2: '到',
requiredMessage3: '個字元',
requiredMessage4: '文字長度為必填參數'
},
showPassword: '密文顯示'
}
}
}

View File

@ -1,5 +1,6 @@
export default {
node: '節點',
nodeName: '節點名稱',
baseComponent: '基礎組件',
nodeSetting: '節點設置',
workflow: '工作流',

View File

@ -150,11 +150,6 @@ export default {
placeholder: '直接返回分段内容',
requiredMessage: '请输入相似度'
},
selectVectorization: {
label: '選擇向量化',
error: '向量化未成功的分段',
all: '全部分段'
}
},
hitHandlingMethod: {
optimization: '模型優化',
@ -169,6 +164,5 @@ export default {
tip4: '生成效果取決於所選模型和提示詞,用戶可自行調整至最佳效果。',
prompt1: `內容:{data}\n\n請總結上面的內容並根據內容總結生成 5 個問題。\n回答要求\n - 請只輸出問題;\n - 請將每個問題放置在`,
prompt2: `標籤中。`,
error: '只執行未成功的分段',
}
}

View File

@ -31,7 +31,6 @@ export default {
title: '關聯分段',
selectDocument: '選擇文件',
placeholder: '按 文件名稱 搜尋',
selectParagraph: '選擇分段',
selectedParagraph: '已選分段',
count: '個'
},

View File

@ -1,15 +1,15 @@
<template>
<el-dialog
v-model="dialogVisible"
:title="$t('views.document.form.selectVectorization.label')"
:title="$t('components.selectParagraph.title')"
:before-close="close"
>
<el-radio-group v-model="state" class="radio-block">
<el-radio value="error" size="large" class="mb-16">{{
$t('views.document.form.selectVectorization.error')
$t('components.selectParagraph.error')
}}</el-radio>
<el-radio value="all" size="large">{{
$t('views.document.form.selectVectorization.all')
$t('components.selectParagraph.all')
}}</el-radio>
</el-radio-group>
<template #footer>

View File

@ -49,7 +49,7 @@
<div class="p-24" style="padding-bottom: 8px; padding-top: 16px">
<div class="flex-between mb-16">
<div class="bold title align-center">
{{ $t('views.problem.relateParagraph.selectParagraph') }}
{{ $t('components.selectParagraph.title') }}
<el-text>
{{ $t('views.problem.relateParagraph.selectedParagraph') }}{{
associationCount(currentDocument)

View File

@ -7,28 +7,14 @@
>
<div v-resize="resizeStepContainer">
<div class="flex-between">
<div
class="flex align-center"
:style="{ maxWidth: node_status == 200 ? 'calc(100% - 85px)' : 'calc(100% - 85px)' }"
>
<div class="flex align-center" style="width: 70%;">
<component
:is="iconComponent(`${nodeModel.type}-icon`)"
class="mr-8"
:size="24"
:item="nodeModel?.properties.node_data"
/>
<h4 v-if="showOperate(nodeModel.type)" style="max-width: 90%">
<ReadWrite
@mousemove.stop
@mousedown.stop
@keydown.stop
@click.stop
@change="editName"
:data="nodeModel.properties.stepName"
trigger="dblclick"
/>
</h4>
<h4 v-else>{{ nodeModel.properties.stepName }}</h4>
<h4 class="ellipsis-1 break-all">{{ nodeModel.properties.stepName }}</h4>
</div>
<div @mousemove.stop @mousedown.stop @keydown.stop @click.stop>
@ -70,6 +56,9 @@
</el-button>
<template #dropdown>
<el-dropdown-menu style="min-width: 80px">
<el-dropdown-item @click="renameNode" class="p-8">{{
$t('common.rename')
}}</el-dropdown-item>
<el-dropdown-item @click="copyNode" class="p-8">{{
$t('common.copy')
}}</el-dropdown-item>
@ -138,6 +127,40 @@
@clickNodes="clickNodes"
/>
</el-collapse-transition>
<el-dialog
:title="$t('views.applicationWorkflow.nodeName')"
v-model="nodeNameDialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:destroy-on-close="true"
append-to-body
>
<el-form label-position="top" ref="titleFormRef" :model="form">
<el-form-item
prop="title"
:rules="[
{
required: true,
message: $t('common.inputPlaceholder'),
trigger: 'blur'
}
]"
>
<el-input v-model="form.title" @blur="form.title = form.title.trim()" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click.prevent="nodeNameDialogVisible = false">
{{ $t('common.cancel') }}
</el-button>
<el-button type="primary" @click="editName(titleFormRef)">
{{ $t('common.save') }}
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
@ -149,6 +172,7 @@ import { iconComponent } from '../icons/utils'
import { copyClick } from '@/utils/clipboard'
import { WorkflowType } from '@/enums/workflow'
import { MsgError, MsgConfirm } from '@/utils/message'
import type { FormInstance } from 'element-plus'
import { t } from '@/locales'
const {
params: { id }
@ -165,6 +189,11 @@ const height = ref<{
})
const showAnchor = ref<boolean>(false)
const anchorData = ref<any>()
const titleFormRef = ref()
const nodeNameDialogVisible = ref<boolean>(false)
const form = ref<any>({
title: ''
})
const condition = computed({
set: (v) => {
@ -190,6 +219,7 @@ const showNode = computed({
return true
}
})
const handleWheel = (event: any) => {
const isCombinationKeyPressed = event.ctrlKey || event.metaKey
if (!isCombinationKeyPressed) {
@ -202,19 +232,30 @@ const node_status = computed(() => {
}
return 200
})
function editName(val: string) {
if (val.trim() && val.trim() !== props.nodeModel.properties.stepName) {
if (
!props.nodeModel.graphModel.nodes?.some(
(node: any) => node.properties.stepName === val.trim()
)
) {
set(props.nodeModel.properties, 'stepName', val.trim())
} else {
MsgError(t('views.applicationWorkflow.tip.repeatedNodeError'))
}
}
function renameNode() {
form.value.title = props.nodeModel.properties.stepName
nodeNameDialogVisible.value = true
}
const editName = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid) => {
if (valid) {
if (
!props.nodeModel.graphModel.nodes?.some(
(node: any) => node.properties.stepName === form.value.title
)
) {
set(props.nodeModel.properties, 'stepName', form.value.title)
nodeNameDialogVisible.value = false
formEl.resetFields()
} else {
MsgError(t('views.applicationWorkflow.tip.repeatedNodeError'))
}
}
})
}
const mousedown = () => {
props.nodeModel.graphModel.clearSelectElements()
set(props.nodeModel, 'isSelected', true)

View File

@ -123,6 +123,7 @@ const currentRow = computed(() => {
const currentIndex = ref(null)
const inputTypeList = ref([
{ label: t('dynamicsForm.input_type_list.TextInput'), value: 'TextInputConstructor' },
{ label: t('dynamicsForm.input_type_list.PasswordInput'), value: 'PasswordInputConstructor' },
{ label: t('dynamicsForm.input_type_list.SingleSelect'), value: 'SingleSelectConstructor' },
{ label: t('dynamicsForm.input_type_list.MultiSelect'), value: 'MultiSelectConstructor' },
{ label: t('dynamicsForm.input_type_list.RadioCard'), value: 'RadioCardConstructor' },

View File

@ -49,6 +49,9 @@
<el-tag type="info" class="info-tag" v-if="row.input_type === 'TextInput'">{{
$t('dynamicsForm.input_type_list.TextInput')
}}</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'PasswordInput'">{{
$t('dynamicsForm.input_type_list.PasswordInput')
}}</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'Slider'">{{
$t('dynamicsForm.input_type_list.Slider')
}}</el-tag>
@ -169,6 +172,9 @@ function refreshFieldTitle(data: any) {
}
const getDefaultValue = (row: any) => {
if(row.input_type === 'PasswordInput') {
return '******'
}
if (row.default_value) {
const default_value = row.option_list
?.filter((v: any) => row.default_value.indexOf(v.value) > -1)

View File

@ -28,7 +28,7 @@
<span class="dialog-footer">
<el-button @click.prevent="dialogVisible = false"> {{ $t('common.cancel') }} </el-button>
<el-button type="primary" @click="submit(fieldFormRef)" :loading="loading">
{{ isEdit ? $t('common.save') : $t('common.add') }}
{{ $t('common.save') }}
</el-button>
</span>
</template>
@ -43,14 +43,15 @@ const emit = defineEmits(['refresh'])
const fieldFormRef = ref()
const loading = ref<boolean>(false)
const isEdit = ref(false)
const form = ref<any>({
title: t('chat.userInput') ,
title: t('chat.userInput')
})
const rules = reactive({
title: [{ required: true, message: t('dynamicsForm.paramForm.name.requiredMessage'), trigger: 'blur' }],
title: [
{ required: true, message: t('dynamicsForm.paramForm.name.requiredMessage'), trigger: 'blur' }
]
})
const dialogVisible = ref<boolean>(false)
@ -58,7 +59,6 @@ const dialogVisible = ref<boolean>(false)
const open = (row: any) => {
if (row) {
form.value = cloneDeep(row)
isEdit.value = true
}
dialogVisible.value = true
@ -66,7 +66,6 @@ const open = (row: any) => {
const close = () => {
dialogVisible.value = false
isEdit.value = false
}
const submit = async (formEl: FormInstance | undefined) => {

View File

@ -39,7 +39,7 @@
<div class="flex-between">
<div>
<span
>{{ $t('views.applicationWorkflow.nodes.variableAssignNode.assign')
>{{ $t('views.applicationWorkflow.nodes.variableAssignNode.assign')
}}<span class="danger">*</span></span
>
</div>
@ -60,77 +60,83 @@
</el-select>
</div>
</template>
</el-form-item>
<div v-if="item.source === 'custom'" class="flex">
<el-row :gutter="8">
<el-col :span="8">
<el-select v-model="item.type" style="width: 130px;">
<el-option v-for="item in typeOptions" :key="item" :label="item"
:value="item" />
</el-select>
</el-col>
<el-col :span="16">
<el-form-item v-if="item.type === 'string'"
:prop="'variable_list.' + index + '.value'"
:rules="{
message: t('dynamicsForm.tip.requiredMessage'),
trigger: 'blur',
required: true
}"
>
<el-input
class="ml-4"
v-model="item.value"
:placeholder="$t('common.inputPlaceholder')"
show-word-limit
clearable
@wheel="wheel"
></el-input>
</el-form-item>
<el-form-item v-else-if="item.type ==='num'"
:prop="'variable_list.' + index + '.value'"
:rules="{
message: t('dynamicsForm.tip.requiredMessage'),
trigger: 'blur',
required: true
}"
>
<el-input-number
class="ml-4"
v-model="item.value"
></el-input-number>
</el-form-item>
<el-form-item v-else-if="item.type === 'json'"
:prop="'variable_list.' + index + '.value'"
:rules="[{
message: t('dynamicsForm.tip.requiredMessage'),
trigger: 'blur',
required: true
},
{
validator: (rule:any, value:any, callback:any) => {
try {
JSON.parse(value);
callback(); // Valid JSON
} catch (e) {
callback(new Error('Invalid JSON format'));
}
},
trigger: 'blur',
}]"
>
<el-input
class="ml-4"
v-model="item.value"
:placeholder="$t('common.inputPlaceholder')"
type="textarea"
></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
<el-form-item v-else>
<div v-if="item.source === 'custom'" class="flex">
<el-row :gutter="8">
<el-col :span="8">
<el-select v-model="item.type" style="width: 85px">
<el-option
v-for="item in typeOptions"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-col>
<el-col :span="16">
<el-form-item
v-if="item.type === 'string'"
:prop="'variable_list.' + index + '.value'"
:rules="{
message: t('dynamicsForm.tip.requiredMessage'),
trigger: 'blur',
required: true
}"
>
<el-input
class="ml-4"
v-model="item.value"
:placeholder="$t('common.inputPlaceholder')"
show-word-limit
clearable
@wheel="wheel"
></el-input>
</el-form-item>
<el-form-item
v-else-if="item.type === 'num'"
:prop="'variable_list.' + index + '.value'"
:rules="{
message: $t('common.inputPlaceholder'),
trigger: 'blur',
required: true
}"
>
<el-input-number class="ml-4" v-model="item.value"></el-input-number>
</el-form-item>
<el-form-item
v-else-if="item.type === 'json'"
:prop="'variable_list.' + index + '.value'"
:rules="[
{
message: $t('common.inputPlaceholder'),
trigger: 'blur',
required: true
},
{
validator: (rule: any, value: any, callback: any) => {
try {
JSON.parse(value)
callback() // Valid JSON
} catch (e) {
callback(new Error('Invalid JSON format'))
}
},
trigger: 'blur'
}
]"
>
<el-input
class="ml-4"
v-model="item.value"
:placeholder="$t('common.inputPlaceholder')"
type="textarea"
autosize
></el-input>
</el-form-item>
</el-col>
</el-row>
</div>
<NodeCascader
v-else
ref="nodeCascaderRef2"
:nodeModel="nodeModel"
class="w-full"
@ -138,7 +144,6 @@
v-model="item.reference"
/>
</el-form-item>
</el-card>
</template>
<el-button link type="primary" @click="addVariable">