feat: i18n

This commit is contained in:
王丹 2025-01-16 18:04:58 +08:00
parent 7eb17bab2f
commit 8fcf935201
15 changed files with 136 additions and 62 deletions

View File

@ -0,0 +1,13 @@
export default {
noHistory: '暂无历史记录',
createChat: '新建对话',
history: '历史记录',
only20history: '仅显示最近 20 条对话',
question_count: '条提问',
exportReords: '导出聊天记录',
passwordValidator: {
title: '请输入密码打开链接',
errorMessage1: '密码不能为空',
errorMessage2: '密码错误'
}
}

View File

@ -1,4 +1,6 @@
import dynamicsForm from './dynamics-form' import dynamicsForm from './dynamics-form'
import chat from './ai-chat'
export default { export default {
dynamicsForm dynamicsForm,
chat
} }

View File

@ -1,3 +1,35 @@
export default { export default {
node: '节点',
baseNodes: '基础组件',
searchBar: {
placeholder: '按名称搜索'
},
info: {
previewVersion: '预览版本:',
saveTime: '保存时间:'
},
setting: {
restoreVersion: '恢复版本',
restoreCurrentVersion: '恢复此版本',
addComponent: '添加组件',
public: '发布',
releaseHistory: '发布历史',
autoSave: '自动保存',
latestRelease: '最近发布'
},
tip: {
publicSuccess: '发布成功',
noData: '没有找到相关结果',
nameMessage: '名字不能为空!',
onlyRight: '只允许从右边的锚点连出',
notRecyclable: '不可循环连线',
onlylest: '只允许连接左边的锚点'
},
variable: {
global: '全局变量',
Referencing: '引用变量',
ReferencingRequired: '引用变量必填',
ReferencingError: '引用变量错误',
NoReferencing:'不存在的引用变量',
}
} }

View File

@ -1,3 +1,6 @@
import Password from '@/views/chat/auth/component/password.vue'
import { create } from 'lodash'
export default { export default {
title: '应用', title: '应用',
createApplication: '创建应用', createApplication: '创建应用',
@ -195,5 +198,6 @@ export default {
text: '针对用户提问调试段落匹配情况,保障回答效果。', text: '针对用户提问调试段落匹配情况,保障回答效果。',
emptyMessage1: '命中段落显示在这里', emptyMessage1: '命中段落显示在这里',
emptyMessage2: '没有命中的分段' emptyMessage2: '没有命中的分段'
} },
} }

View File

@ -11,6 +11,7 @@ import document from './document';
import paragraph from './paragraph'; import paragraph from './paragraph';
import problem from './problem'; import problem from './problem';
import log from './log'; import log from './log';
import applicationWorkflow from './application-workflow';
export default { export default {
notFound, notFound,
application, application,
@ -24,5 +25,6 @@ export default {
document, document,
paragraph, paragraph,
problem, problem,
log log,
applicationWorkflow
}; };

View File

@ -2,14 +2,18 @@
<div v-show="show" class="workflow-dropdown-menu border border-r-4"> <div v-show="show" class="workflow-dropdown-menu border border-r-4">
<el-tabs v-model="activeName" class="workflow-dropdown-tabs"> <el-tabs v-model="activeName" class="workflow-dropdown-tabs">
<div style="display: flex; width: 100%; justify-content: center" class="mb-4"> <div style="display: flex; width: 100%; justify-content: center" class="mb-4">
<el-input v-model="search_text" style="width: 240px" placeholder="按名称搜索"> <el-input
v-model="search_text"
style="width: 240px"
:placeholder="$t('views.applicationWorkflow.searchBar.placeholder')"
>
<template #suffix> <template #suffix>
<el-icon class="el-input__icon"><search /></el-icon> <el-icon class="el-input__icon"><search /></el-icon>
</template> </template>
</el-input> </el-input>
</div> </div>
<el-tab-pane label="基础组件" name="base"> <el-tab-pane :label="$t('views.applicationWorkflow.baseNodes')" name="base">
<el-scrollbar height="400"> <el-scrollbar height="400">
<div v-if="filter_menu_nodes.length > 0"> <div v-if="filter_menu_nodes.length > 0">
<template v-for="(item, index) in filter_menu_nodes" :key="index"> <template v-for="(item, index) in filter_menu_nodes" :key="index">
@ -27,11 +31,11 @@
</template> </template>
</div> </div>
<div v-else class="ml-16 mt-8"> <div v-else class="ml-16 mt-8">
<el-text type="info">没有找到相关结果</el-text> <el-text type="info">{{ $t('views.applicationWorkflow.tip.noData') }}</el-text>
</div> </div>
</el-scrollbar> </el-scrollbar>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="函数库" name="function"> <el-tab-pane :label="$t('views.functionLib.title')" name="function">
<el-scrollbar height="400"> <el-scrollbar height="400">
<div <div
class="workflow-dropdown-item cursor flex p-8-12" class="workflow-dropdown-item cursor flex p-8-12"
@ -69,7 +73,7 @@
</template> </template>
</el-scrollbar> </el-scrollbar>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="应用" name="application"> <el-tab-pane :label="$t('views.application.title')" name="application">
<el-scrollbar height="400"> <el-scrollbar height="400">
<div v-if="filter_application_list.length > 0"> <div v-if="filter_application_list.length > 0">
<template v-for="(item, index) in filter_application_list" :key="index"> <template v-for="(item, index) in filter_application_list" :key="index">
@ -100,16 +104,18 @@
</p> </p>
</div> </div>
<div class="status-tag" style="margin-left: auto"> <div class="status-tag" style="margin-left: auto">
<el-tag type="warning" v-if="isWorkFlow(item.type)" style="height: 22px" <el-tag type="warning" v-if="isWorkFlow(item.type)" style="height: 22px">
>高级编排</el-tag {{ $t('views.application.workflow') }}</el-tag
> >
<el-tag class="blue-tag" v-else style="height: 22px">简单配置</el-tag> <el-tag class="blue-tag" v-else style="height: 22px">{{
$t('views.application.simple')
}}</el-tag>
</div> </div>
</div> </div>
</template> </template>
</div> </div>
<div v-else class="ml-16 mt-8"> <div v-else class="ml-16 mt-8">
<el-text type="info">没有找到相关结果</el-text> <el-text type="info">{{ $t('views.applicationWorkflow.tip.noData') }}</el-text>
</div> </div>
</el-scrollbar> </el-scrollbar>
</el-tab-pane> </el-tab-pane>

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="workflow-publish-history border-l"> <div class="workflow-publish-history border-l">
<h4 class="border-b p-16-24">发布历史</h4> <h4 class="border-b p-16-24">{{ $t('views.applicationWorkflow.setting.releaseHistory') }}</h4>
<div class="list-height pt-0"> <div class="list-height pt-0">
<el-scrollbar> <el-scrollbar>
<div class="p-8 pt-0"> <div class="p-8 pt-0">
@ -23,7 +23,9 @@
:write="row.writeStatus" :write="row.writeStatus"
@close="closeWrite(row)" @close="closeWrite(row)"
/> />
<el-tag v-if="index === 0" class="default-tag ml-4">最近发布</el-tag> <el-tag v-if="index === 0" class="default-tag ml-4">{{
$t('views.applicationWorkflow.setting.latestRelease')
}}</el-tag>
</h5> </h5>
<el-text type="info" class="color-secondary flex mt-8"> <el-text type="info" class="color-secondary flex mt-8">
<AppAvatar :size="20" class="avatar-grey mr-4"> <AppAvatar :size="20" class="avatar-grey mr-4">
@ -46,7 +48,7 @@
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item @click="refreshVersion(row)"> <el-dropdown-item @click="refreshVersion(row)">
<el-icon><RefreshLeft /></el-icon> <el-icon><RefreshLeft /></el-icon>
恢复此版本 {{ $t('views.applicationWorkflow.setting.restoreCurrentVersion') }}
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
@ -57,7 +59,7 @@
<template #empty> <template #empty>
<div class="text-center"> <div class="text-center">
<el-text type="info">暂无历史记录</el-text> <el-text type="info"> {{ $t('components.chat.noHistory') }}</el-text>
</div> </div>
</template> </template>
</common-list> </common-list>
@ -72,6 +74,7 @@ import { useRoute } from 'vue-router'
import applicationApi from '@/api/application' import applicationApi from '@/api/application'
import { datetimeFormat } from '@/utils/time' import { datetimeFormat } from '@/utils/time'
import { MsgSuccess, MsgError } from '@/utils/message' import { MsgSuccess, MsgError } from '@/utils/message'
import { t } from '@/locales'
const route = useRoute() const route = useRoute()
const { const {
params: { id } params: { id }
@ -114,7 +117,7 @@ function editName(val: string, item: any) {
getList() getList()
}) })
} else { } else {
MsgError('名字不能为空!') MsgError(t('views.applicationWorkflow.tip.nameMessage'))
} }
} }

View File

@ -8,23 +8,26 @@
<h4>{{ detail?.name }}</h4> <h4>{{ detail?.name }}</h4>
<div v-if="showHistory && disablePublic"> <div v-if="showHistory && disablePublic">
<el-text type="info" class="ml-16 color-secondary" <el-text type="info" class="ml-16 color-secondary"
>预览版本 >{{ $t('views.applicationWorkflow.info.previewVersion') }}
{{ currentVersion.name || datetimeFormat(currentVersion.update_time) }}</el-text {{ currentVersion.name || datetimeFormat(currentVersion.update_time) }}</el-text
> >
</div> </div>
<el-text type="info" class="ml-16 color-secondary" v-else-if="saveTime" <el-text type="info" class="ml-16 color-secondary" v-else-if="saveTime"
>保存时间{{ datetimeFormat(saveTime) }}</el-text >{{ $t('views.applicationWorkflow.info.saveTime')
}}{{ datetimeFormat(saveTime) }}</el-text
> >
</div> </div>
<div v-if="showHistory && disablePublic"> <div v-if="showHistory && disablePublic">
<el-button type="primary" class="mr-8" @click="refreshVersion()"> 恢复版本 </el-button> <el-button type="primary" class="mr-8" @click="refreshVersion()">
{{ $t('views.applicationWorkflow.setting.restoreVersion') }}
</el-button>
<el-divider direction="vertical" /> <el-divider direction="vertical" />
<el-button text @click="closeHistory"> <el-button text @click="closeHistory">
<el-icon><Close /></el-icon> <el-icon><Close /></el-icon>
</el-button> </el-button>
</div> </div>
<div v-else> <div v-else>
<el-button icon="Plus" @click="showPopover = !showPopover"> 添加组件 </el-button> <el-button icon="Plus" @click="showPopover = !showPopover"> {{ $t('views.applicationWorkflow.setting.addComponent') }} </el-button>
<el-button @click="clickShowDebug" :disabled="showDebug"> <el-button @click="clickShowDebug" :disabled="showDebug">
<AppIcon iconName="app-play-outlined" class="mr-4"></AppIcon> <AppIcon iconName="app-play-outlined" class="mr-4"></AppIcon>
{{ $t('common.debug') }}</el-button {{ $t('common.debug') }}</el-button
@ -33,7 +36,7 @@
<AppIcon iconName="app-save-outlined" class="mr-4"></AppIcon> <AppIcon iconName="app-save-outlined" class="mr-4"></AppIcon>
{{ $t('common.save') }} {{ $t('common.save') }}
</el-button> </el-button>
<el-button type="primary" @click="publicHandle"> 发布 </el-button> <el-button type="primary" @click="publicHandle"> {{ $t('views.applicationWorkflow.setting.public') }} </el-button>
<el-dropdown trigger="click"> <el-dropdown trigger="click">
<el-button text @click.stop class="ml-8 mt-4"> <el-button text @click.stop class="ml-8 mt-4">
@ -43,11 +46,11 @@
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="openHistory"> <el-dropdown-item @click="openHistory">
<AppIcon iconName="app-history-outlined"></AppIcon> <AppIcon iconName="app-history-outlined"></AppIcon>
发布历史 {{ $t('views.applicationWorkflow.setting.releaseHistory') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item> <el-dropdown-item>
<AppIcon iconName="app-save-outlined"></AppIcon> <AppIcon iconName="app-save-outlined"></AppIcon>
自动保存 {{ $t('views.applicationWorkflow.setting.autoSave') }}
<div class="ml-4"> <div class="ml-4">
<el-switch size="small" v-model="isSave" @change="changeSave" /> <el-switch size="small" v-model="isSave" @change="changeSave" />
</div> </div>
@ -146,7 +149,7 @@ import { datetimeFormat } from '@/utils/time'
import useStore from '@/stores' import useStore from '@/stores'
import { WorkFlowInstance } from '@/workflow/common/validate' import { WorkFlowInstance } from '@/workflow/common/validate'
import { hasPermission } from '@/utils/permission' import { hasPermission } from '@/utils/permission'
import { t } from '@/locales'
const { user, application } = useStore() const { user, application } = useStore()
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
@ -258,17 +261,17 @@ async function publicHandle() {
return return
} }
applicationApi.putPublishApplication(id as String, obj, loading).then(() => { applicationApi.putPublishApplication(id as String, obj, loading).then(() => {
MsgSuccess('发布成功') MsgSuccess(t('views.applicationWorkflow.tip.publicSuccess'))
}) })
}) })
.catch((res: any) => { .catch((res: any) => {
const node = res.node const node = res.node
const err_message = res.errMessage const err_message = res.errMessage
if (typeof err_message == 'string') { if (typeof err_message == 'string') {
MsgError(res.node.properties?.stepName + '节点 ' + err_message) MsgError(res.node.properties?.stepName + `${t('views.applicationWorkflow.node')} ` + err_message)
} else { } else {
const keys = Object.keys(err_message) const keys = Object.keys(err_message)
MsgError(node.properties?.stepName + '节点 ' + err_message[keys[0]]?.[0]?.message) MsgError(node.properties?.stepName + `${t('views.applicationWorkflow.node')} ` + err_message[keys[0]]?.[0]?.message)
} }
}) })
} }
@ -297,10 +300,10 @@ const clickShowDebug = () => {
const node = res.node const node = res.node
const err_message = res.errMessage const err_message = res.errMessage
if (typeof err_message == 'string') { if (typeof err_message == 'string') {
MsgError(res.node.properties?.stepName + '节点 ' + err_message) MsgError(res.node.properties?.stepName + `${t('views.applicationWorkflow.node')} ` + err_message)
} else { } else {
const keys = Object.keys(err_message) const keys = Object.keys(err_message)
MsgError(node.properties?.stepName + '节点 ' + err_message[keys[0]]?.[0]?.message) MsgError(node.properties?.stepName + `${t('views.applicationWorkflow.node')} ` + err_message[keys[0]]?.[0]?.message)
} }
}) })
} }

View File

@ -3,7 +3,7 @@
:modelValue="show" :modelValue="show"
modal-class="positioned-mask" modal-class="positioned-mask"
width="300" width="300"
title="请输入密码打开链接" :title="$t('components.chat.passwordValidator.title')"
custom-class="no-close-button" custom-class="no-close-button"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
@ -26,6 +26,7 @@
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import useStore from '@/stores' import useStore from '@/stores'
import { t } from '@/locales'
const route = useRoute() const route = useRoute()
const FormRef = ref() const FormRef = ref()
const { const {
@ -51,10 +52,10 @@ const auth = () => {
} }
const validator_auth = (rule: any, value: string, callback: any) => { const validator_auth = (rule: any, value: string, callback: any) => {
if (value === '') { if (value === '') {
callback(new Error('密码不能为空')) callback(new Error(t('components.chat.passwordValidator.errorMessage1')))
} else { } else {
auth().catch(() => { auth().catch(() => {
callback(new Error('密码错误')) callback(new Error(t('components.chat.passwordValidator.errorMessage2')))
}) })
} }
} }

View File

@ -47,7 +47,8 @@
<template #operateBefore> <template #operateBefore>
<div class="chat-width"> <div class="chat-width">
<el-button type="primary" link class="new-chat-button mb-8" @click="newChat"> <el-button type="primary" link class="new-chat-button mb-8" @click="newChat">
<el-icon><Plus /></el-icon><span class="ml-4"></span> <el-icon><Plus /></el-icon
><span class="ml-4">{{ $t('components.chat.createChat') }}</span>
</el-button> </el-button>
</div> </div>
</template> </template>
@ -71,7 +72,7 @@
<el-collapse-transition> <el-collapse-transition>
<div v-show="show" class="chat-popover w-full" v-click-outside="clickoutside"> <div v-show="show" class="chat-popover w-full" v-click-outside="clickoutside">
<div class="border-b p-16-24"> <div class="border-b p-16-24">
<span>历史记录</span> <span>{{ $t('components.chat.history') }}</span>
</div> </div>
<el-scrollbar max-height="300"> <el-scrollbar max-height="300">
@ -99,13 +100,13 @@
</template> </template>
<template #empty> <template #empty>
<div class="text-center mt-24"> <div class="text-center mt-24">
<el-text type="info">暂无历史记录</el-text> <el-text type="info">{{ $t('components.chat.noHistory') }}</el-text>
</div> </div>
</template> </template>
</common-list> </common-list>
</div> </div>
<div v-if="chatLogData.length" class="gradient-divider lighter mt-8"> <div v-if="chatLogData.length" class="gradient-divider lighter mt-8">
<span>仅显示最近 20 条对话</span> <span>{{ $t('components.chat.only20history') }}</span>
</div> </div>
</el-scrollbar> </el-scrollbar>
</div> </div>
@ -119,7 +120,6 @@ import { ref, onMounted, reactive, nextTick, computed } from 'vue'
import { isAppIcon } from '@/utils/application' import { isAppIcon } from '@/utils/application'
import { hexToRgba } from '@/utils/theme' import { hexToRgba } from '@/utils/theme'
import useStore from '@/stores' import useStore from '@/stores'
const { user, log } = useStore() const { user, log } = useStore()
const AiChatRef = ref() const AiChatRef = ref()

View File

@ -38,9 +38,9 @@
<el-icon> <el-icon>
<Plus /> <Plus />
</el-icon> </el-icon>
<span class="ml-4">新建对话</span> <span class="ml-4">{{ $t('components.chat.createChat') }}</span>
</el-button> </el-button>
<p class="mt-20 mb-8">历史记录</p> <p class="mt-20 mb-8">{{ $t('components.chat.history') }}</p>
</div> </div>
<div class="left-height pt-0"> <div class="left-height pt-0">
<el-scrollbar> <el-scrollbar>
@ -76,13 +76,13 @@
<template #empty> <template #empty>
<div class="text-center"> <div class="text-center">
<el-text type="info">暂无历史记录</el-text> <el-text type="info">{{ $t('components.chat.noHistory') }}</el-text>
</div> </div>
</template> </template>
</common-list> </common-list>
</div> </div>
<div v-if="chatLogData?.length" class="gradient-divider lighter mt-8"> <div v-if="chatLogData?.length" class="gradient-divider lighter mt-8">
<span>仅显示最近 20 条对话</span> <span>{{ $t('components.chat.only20history') }}</span>
</div> </div>
</el-scrollbar> </el-scrollbar>
</div> </div>
@ -101,14 +101,18 @@
style="font-size: 16px" style="font-size: 16px"
></AppIcon> ></AppIcon>
<span v-if="paginationConfig.total" class="lighter"> <span v-if="paginationConfig.total" class="lighter">
{{ paginationConfig.total }} 条提问 {{ paginationConfig.total }} {{ $t('components.chat.question_count') }}
</span> </span>
<el-dropdown class="ml-8"> <el-dropdown class="ml-8">
<AppIcon iconName="app-export" class="cursor" title="导出聊天记录"></AppIcon> <AppIcon
iconName="app-export"
class="cursor"
:title="$t('components.chat.exportReords')"
></AppIcon>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="exportMarkdown">导出 Markdown</el-dropdown-item> <el-dropdown-item @click="exportMarkdown">{{ $t('common.exprt') }} Markdown</el-dropdown-item>
<el-dropdown-item @click="exportHTML">导出 HTML</el-dropdown-item> <el-dropdown-item @click="exportHTML">{{ $t('common.exprt') }} HTML</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
@ -147,7 +151,7 @@ import { isAppIcon } from '@/utils/application'
import useStore from '@/stores' import useStore from '@/stores'
import useResize from '@/layout/hooks/useResize' import useResize from '@/layout/hooks/useResize'
import { hexToRgba } from '@/utils/theme' import { hexToRgba } from '@/utils/theme'
import { t } from '@/locales'
useResize() useResize()
const { user, log, common } = useStore() const { user, log, common } = useStore()
@ -175,7 +179,7 @@ const classObj = computed(() => {
const newObj = { const newObj = {
id: 'new', id: 'new',
abstract: '新建对话' abstract: t('components.chat.createChat')
} }
const props = defineProps<{ const props = defineProps<{
application_profile: any application_profile: any
@ -202,7 +206,7 @@ const paginationConfig = ref({
const currentRecordList = ref<any>([]) const currentRecordList = ref<any>([])
const currentChatId = ref('new') // Id 'new' const currentChatId = ref('new') // Id 'new'
const currentChatName = ref('新建对话') const currentChatName = ref(t('components.chat.createChat'))
const mouseId = ref('') const mouseId = ref('')
function mouseenter(row: any) { function mouseenter(row: any) {
@ -212,7 +216,7 @@ function deleteLog(row: any) {
log.asyncDelChatClientLog(applicationDetail.value.id, row.id, left_loading).then(() => { log.asyncDelChatClientLog(applicationDetail.value.id, row.id, left_loading).then(() => {
if (currentChatId.value === row.id) { if (currentChatId.value === row.id) {
currentChatId.value = 'new' currentChatId.value = 'new'
currentChatName.value = '新建对话' currentChatName.value = t('components.chat.createChat')
paginationConfig.value.current_page = 1 paginationConfig.value.current_page = 1
paginationConfig.value.total = 0 paginationConfig.value.total = 0
currentRecordList.value = [] currentRecordList.value = []
@ -247,7 +251,7 @@ function newChat() {
currentRecordList.value = [] currentRecordList.value = []
} }
currentChatId.value = 'new' currentChatId.value = 'new'
currentChatName.value = '新建对话' currentChatName.value = t('components.chat.createChat')
if (common.isMobile()) { if (common.isMobile()) {
isCollapse.value = false isCollapse.value = false
} }

View File

@ -25,9 +25,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import DynamicsFormConstructor from '@/components/dynamics-form/constructor/index.vue' import DynamicsFormConstructor from '@/components/dynamics-form/constructor/index.vue'
import { t } from '@/locales'
const props = withDefaults( const props = withDefaults(
defineProps<{ title?: string; addFormField: (form_data: any) => void }>(), defineProps<{ title?: string; addFormField: (form_data: any) => void }>(),
{ title: '添加参数' } { title: t('views.template.templateForm.title.addParam') }
) )
const dialogVisible = ref<boolean>(false) const dialogVisible = ref<boolean>(false)
const dynamicsFormConstructorRef = ref<InstanceType<typeof DynamicsFormConstructor>>() const dynamicsFormConstructorRef = ref<InstanceType<typeof DynamicsFormConstructor>>()

View File

@ -27,9 +27,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import DynamicsFormConstructor from '@/components/dynamics-form/constructor/index.vue' import DynamicsFormConstructor from '@/components/dynamics-form/constructor/index.vue'
import { t } from '@/locales'
const props = withDefaults( const props = withDefaults(
defineProps<{ title?: string; editFormField: (form_data: any, index: number) => void }>(), defineProps<{ title?: string; editFormField: (form_data: any, index: number) => void }>(),
{ title: '修改参数' } { title: t('views.template.templateForm.title.editParam') }
) )
const dialogVisible = ref<boolean>(false) const dialogVisible = ref<boolean>(false)
const dynamicsFormConstructorRef = ref<InstanceType<typeof DynamicsFormConstructor>>() const dynamicsFormConstructorRef = ref<InstanceType<typeof DynamicsFormConstructor>>()

View File

@ -21,6 +21,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, computed } from 'vue' import { ref, onMounted, computed } from 'vue'
import { iconComponent } from '../icons/utils' import { iconComponent } from '../icons/utils'
import { t } from '@/locales'
const props = defineProps<{ const props = defineProps<{
nodeModel: any nodeModel: any
modelValue: Array<any> modelValue: Array<any>
@ -69,7 +70,7 @@ function _getIncomingNode(id: String, startId: String, value: Array<any>) {
if (item.properties?.globalFields && item.type === 'start-node') { if (item.properties?.globalFields && item.type === 'start-node') {
firstElement = { firstElement = {
value: 'global', value: 'global',
label: '全局变量', label: t('views.applicationWorkflow.variable.global'),
type: 'global', type: 'global',
children: item.properties?.config?.globalFields || [] children: item.properties?.config?.globalFields || []
} }
@ -94,21 +95,21 @@ const validate = () => {
const incomingNodeValue = getIncomingNode(props.nodeModel.id) const incomingNodeValue = getIncomingNode(props.nodeModel.id)
options.value = incomingNodeValue options.value = incomingNodeValue
if (!data.value || data.value.length === 0) { if (!data.value || data.value.length === 0) {
return Promise.reject('引用变量必填') return Promise.reject(t('views.applicationWorkflow.variable.ReferencingRequired'))
} }
if (data.value.length < 2) { if (data.value.length < 2) {
return Promise.reject('引用变量错误') return Promise.reject(t('views.applicationWorkflow.variable.ReferencingError'))
} }
const node_id = data.value[0] const node_id = data.value[0]
const node_field = data.value[1] const node_field = data.value[1]
const nodeParent = incomingNodeValue.find((item: any) => item.value === node_id) const nodeParent = incomingNodeValue.find((item: any) => item.value === node_id)
if (!nodeParent) { if (!nodeParent) {
data.value = [] data.value = []
return Promise.reject('不存在的引用变量') return Promise.reject(t('views.applicationWorkflow.variable.NoReferencing'))
} }
if (!nodeParent.children.some((item: any) => item.value === node_field)) { if (!nodeParent.children.some((item: any) => item.value === node_field)) {
data.value = [] data.value = []
return Promise.reject('不存在的引用变量') return Promise.reject(t('views.applicationWorkflow.variable.NoReferencing'))
} }
return Promise.resolve('') return Promise.resolve('')
} }

View File

@ -276,6 +276,7 @@ class AppNodeModel extends HtmlResize.model {
} }
setAttributes() { setAttributes() {
const { t } = i18n.global;
this.width = this.get_width() this.width = this.get_width()
const isLoop = (node_id: string, target_node_id: string) => { const isLoop = (node_id: string, target_node_id: string) => {
const up_node_list = this.graphModel.getNodeIncomingNode(node_id) const up_node_list = this.graphModel.getNodeIncomingNode(node_id)
@ -293,13 +294,13 @@ class AppNodeModel extends HtmlResize.model {
return false return false
} }
const circleOnlyAsTarget = { const circleOnlyAsTarget = {
message: '只允许从右边的锚点连出', message: t('views.applicationWorkflow.tip.onlyRight'),
validate: (sourceNode: any, targetNode: any, sourceAnchor: any) => { validate: (sourceNode: any, targetNode: any, sourceAnchor: any) => {
return sourceAnchor.type === 'right' return sourceAnchor.type === 'right'
} }
} }
this.sourceRules.push({ this.sourceRules.push({
message: '不可循环连线', message: t('views.applicationWorkflow.tip.notRecyclable'),
validate: (sourceNode: any, targetNode: any, sourceAnchor: any, targetAnchor: any) => { validate: (sourceNode: any, targetNode: any, sourceAnchor: any, targetAnchor: any) => {
return !isLoop(sourceNode.id, targetNode.id) return !isLoop(sourceNode.id, targetNode.id)
} }
@ -307,7 +308,7 @@ class AppNodeModel extends HtmlResize.model {
this.sourceRules.push(circleOnlyAsTarget) this.sourceRules.push(circleOnlyAsTarget)
this.targetRules.push({ this.targetRules.push({
message: '只允许连接左边的锚点', message: t('views.applicationWorkflow.tip.onlylest'),
validate: (sourceNode: any, targetNode: any, sourceAnchor: any, targetAnchor: any) => { validate: (sourceNode: any, targetNode: any, sourceAnchor: any, targetAnchor: any) => {
return targetAnchor.type === 'left' return targetAnchor.type === 'left'
} }