Commit daf2a679 authored by tyyin lan's avatar tyyin lan

feat: 智能表单(出差表单)

parent 6bd7de7c
...@@ -855,3 +855,20 @@ editor_module: ...@@ -855,3 +855,20 @@ editor_module:
serious_and_formal: 'Serious and formal' serious_and_formal: 'Serious and formal'
concise_and_clear: 'Concise and clear' concise_and_clear: 'Concise and clear'
elegant_literary_style: 'Elegant literary style' elegant_literary_style: 'Elegant literary style'
smart_forms_module:
business_trip_form:
title: 'Business trip form'
objective: 'Objective'
travel_location: 'Travel location'
departure_time: 'Departure time'
return_time: 'Return time'
vehicle: 'Vehicle'
estimated_cost: 'Estimated cost'
residence: 'Residence'
estimated_amount: 'Estimated amount'
general_budget: 'General budget'
email: 'Email'
confirm_submission: 'Confirm submission'
please_enter_the: 'Please enter the'
execution_successful_doc: 'Execution successful doc'
...@@ -853,3 +853,20 @@ editor_module: ...@@ -853,3 +853,20 @@ editor_module:
serious_and_formal: '严肃正式' serious_and_formal: '严肃正式'
concise_and_clear: '简洁明了' concise_and_clear: '简洁明了'
elegant_literary_style: '文采优美' elegant_literary_style: '文采优美'
smart_forms_module:
business_trip_form:
title: '出差表单'
objective: '出差目的'
travel_location: '出差地点'
departure_time: '出发时间'
return_time: '返回时间'
vehicle: '交通工具'
estimated_cost: '预计费用'
residence: '住宿地点'
estimated_amount: '预计金额'
general_budget: '总预算'
email: '邮箱信息'
confirm_submission: '确认提交'
please_enter_the: '请输入'
execution_successful_doc: '出差表单插件执行成功'
...@@ -853,3 +853,20 @@ editor_module: ...@@ -853,3 +853,20 @@ editor_module:
serious_and_formal: '嚴肅正式' serious_and_formal: '嚴肅正式'
concise_and_clear: '簡潔明了' concise_and_clear: '簡潔明了'
elegant_literary_style: '文采優美' elegant_literary_style: '文采優美'
smart_forms_module:
business_trip_form:
title: '出差表單'
objective: '出差目的'
travel_location: '出差地點'
departure_time: '出發時間'
return_time: '返回時間'
vehicle: '交通工具'
estimated_cost: '預計費用'
residence: '住宿地點'
estimated_amount: '預計金額'
general_budget: '總預算'
email: '郵箱信息'
confirm_submission: '確認提交'
please_enter_the: '請輸入'
execution_successful_doc: '出差表單插件執行成功'
...@@ -44,6 +44,9 @@ export const useSystemLanguageStore = defineStore('system-language-store', { ...@@ -44,6 +44,9 @@ export const useSystemLanguageStore = defineStore('system-language-store', {
currentLanguage(state): I18n.LangType { currentLanguage(state): I18n.LangType {
return state.currentLanguageInfo.key return state.currentLanguageInfo.key
}, },
isEnglishLanguage(state) {
return state.currentLanguageInfo.key === 'en'
},
}, },
actions: { actions: {
updateCurrentLanguageInfo(key: I18n.LangType) { updateCurrentLanguageInfo(key: I18n.LangType) {
......
<script setup lang="ts">
import { ref } from 'vue'
import { MessageItemInterface } from '../types'
import { useI18n } from 'vue-i18n'
interface Props {
isAgentMessage: boolean
messageItem: MessageItemInterface
messageAuthor: string
}
defineProps<Props>()
const { t } = useI18n()
const isShowReasoningContent = ref(true)
function handleShowReasoningContentSwitch() {
isShowReasoningContent.value = !isShowReasoningContent.value
}
</script>
<template>
<template v-if="isAgentMessage && messageItem.name === 'Deepseek R1'">
<div class="mb-[7px] select-none text-[14px]">
<div
class="inline-flex cursor-pointer items-center transition-[color] duration-200 ease-in-out hover:!text-[#777ef9]"
@click="handleShowReasoningContentSwitch"
>
<span class="mr-[8px]">{{ messageAuthor }}</span>
<i
class="iconfont icon-left rotate-[90deg] text-[12px] transition-[transform] duration-200 ease-in-out"
:class="{ '!rotate-[270deg]': isShowReasoningContent }"
></i>
</div>
</div>
<Transition>
<div v-show="isShowReasoningContent" class="h-fit">
<div class="mb-[14px] border-l-[1px] border-solid border-l-[#ccc] p-[13px]">
<div>
<img
v-if="!messageItem.reasoningContent && !messageItem.content"
src="@/assets/images/home/bubble-loading.gif"
alt="bubble-loading"
/>
<template v-else>
<MarkdownRender
ref="markdownRenderRef"
:raw-text-content="
messageItem.reasoningContent
? messageItem.reasoningContent
: t('common_module.dialogue_module.empty_message_content')
"
color="#999"
/>
</template>
</div>
</div>
</div>
</Transition>
</template>
<div v-else class="mb-[7px] text-[12px] text-[#999]">
{{ messageAuthor }}
</div>
</template>
<style lang="scss" scoped>
.v-enter-active,
.v-leave-active {
overflow: hidden;
transition-timing-function: ease-in-out;
transition-duration: 0.3s;
transition-property: opacity height;
}
.v-enter-from,
.v-leave-to {
height: 0 !important;
opacity: 0;
}
</style>
<script setup lang="ts"> <script setup lang="ts">
import { computed, readonly, ref, useTemplateRef } from 'vue' import { computed, readonly, useTemplateRef } from 'vue'
import { CheckOne, Down } from '@icon-park/vue-next' import { CheckOne } from '@icon-park/vue-next'
import type { MessageItemInterface } from '../types' import type { MessageItemInterface } from '../types'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import MessageBubbleLoading from './message-bubble-loading.vue' import MessageBubbleLoading from './message-bubble-loading.vue'
...@@ -8,6 +8,9 @@ import { useI18n } from 'vue-i18n' ...@@ -8,6 +8,9 @@ import { useI18n } from 'vue-i18n'
import { copyToClip } from '@/utils/copy' import { copyToClip } from '@/utils/copy'
import { throttle } from 'lodash-es' import { throttle } from 'lodash-es'
import MarkdownRender from '@/components/markdown-render/markdown-render.vue' import MarkdownRender from '@/components/markdown-render/markdown-render.vue'
// import ExecuteCodeRender from '@/components/execute-code-render/execute-code-render.vue'
import SmartForms from './smart-forms/index.vue'
import AuthorInfo from './author-info.vue'
interface Props { interface Props {
messageItem: MessageItemInterface messageItem: MessageItemInterface
...@@ -24,7 +27,6 @@ const userStore = useUserStore() ...@@ -24,7 +27,6 @@ const userStore = useUserStore()
const markdownRenderRef = useTemplateRef<InstanceType<typeof MarkdownRender>>('markdownRenderRef') const markdownRenderRef = useTemplateRef<InstanceType<typeof MarkdownRender>>('markdownRenderRef')
const agentDefaultAvatarUrl = readonly({ url: 'https://gsst-poe-sit.gz.bcebos.com/icon/agent-avatar.png' }) const agentDefaultAvatarUrl = readonly({ url: 'https://gsst-poe-sit.gz.bcebos.com/icon/agent-avatar.png' })
const isShowReasoningContent = ref(true)
const isAgentMessage = computed(() => { const isAgentMessage = computed(() => {
return props.messageItem.role === 'assistant' return props.messageItem.role === 'assistant'
...@@ -39,13 +41,9 @@ const messageAuthor = computed(() => { ...@@ -39,13 +41,9 @@ const messageAuthor = computed(() => {
}) })
const currentBubbleTextColor = computed(() => { const currentBubbleTextColor = computed(() => {
return isAgentMessage.value ? '#fff' : '#192338' return isAgentMessage.value ? '#192338' : '#fff'
}) })
function handleShowReasoningContentSwitch() {
isShowReasoningContent.value = !isShowReasoningContent.value
}
const handleContentCopy = throttle( const handleContentCopy = throttle(
() => { () => {
copyToClip(props.messageItem.content).then(() => { copyToClip(props.messageItem.content).then(() => {
...@@ -74,54 +72,13 @@ const handleContentEdit = throttle( ...@@ -74,54 +72,13 @@ const handleContentEdit = throttle(
<div class="flex"> <div class="flex">
<img class="h-[36px] w-[36px] rounded-[6px] object-cover" :src="avatarUrl" alt="Avatar" /> <img class="h-[36px] w-[36px] rounded-[6px] object-cover" :src="avatarUrl" alt="Avatar" />
<div class="ml-[11px] overflow-hidden"> <div v-if="true" class="ml-[11px] overflow-hidden">
<template v-if="isAgentMessage && messageItem.name === 'Deepseek R1'"> <AuthorInfo :is-agent-message="isAgentMessage" :message-item="messageItem" :message-author="messageAuthor" />
<div class="mb-[7px] select-none text-[14px]">
<div class="inline-flex cursor-pointer" @click="handleShowReasoningContentSwitch">
<span class="mr-[6px]">{{ messageAuthor }}</span>
<Down
theme="outline"
size="21"
fill="#333"
:stroke-width="3"
class="transition-[rotate] duration-100 ease-linear"
:class="{ '-rotate-180': isShowReasoningContent }"
/>
</div>
</div>
<n-collapse-transition :show="isShowReasoningContent">
<div class="my-[14px] border-l-[1px] border-solid border-l-[#ccc] p-[13px]">
<div>
<img
v-if="!messageItem.reasoningContent && !messageItem.content"
src="@/assets/images/home/bubble-loading.gif"
alt="bubble-loading"
/>
<template v-else>
<MarkdownRender
ref="markdownRenderRef"
:raw-text-content="
messageItem.reasoningContent
? messageItem.reasoningContent
: t('common_module.dialogue_module.empty_message_content')
"
color="#999"
/>
</template>
</div>
</div>
</n-collapse-transition>
</template>
<div v-else class="mb-[7px] text-[12px] text-[#999]">
{{ messageAuthor }}
</div>
<div <div
class="box-content min-h-[21px] min-w-[10px] max-w-full rounded-[10px] border border-[#9EA3FF] px-[15px] py-[14px] text-justify" class="box-content min-h-[21px] min-w-[10px] max-w-full rounded-[10px] border border-[#9EA3FF] bg-[#777EF9] px-[15px] py-[14px] text-justify"
:class="{ :class="{
'bg-[#777EF9]': isAgentMessage, '!bg-[#fff]': isAgentMessage,
'text-[#fff]': isAgentMessage,
'!min-w-[80px]': messageItem.isAnswerLoading, '!min-w-[80px]': messageItem.isAnswerLoading,
}" }"
> >
...@@ -137,12 +94,18 @@ const handleContentEdit = throttle( ...@@ -137,12 +94,18 @@ const handleContentEdit = throttle(
<MessageBubbleLoading :active-color="currentBubbleTextColor" /> <MessageBubbleLoading :active-color="currentBubbleTextColor" />
</div> </div>
<template v-else> <template v-else>
<!-- <ExecuteCodeRender
title="数据库问答执行成功"
:raw-text-content="`\`\`\`SQL\nSELECT type, channel, total_points, usage_count, users_count, data_date SELECT type, channel, total_points, usage_count, users_count, data_date SELECT type, channel, total_points, usage_count, users_count, data_date SELECT type, channel, total_points, usage_count, users_count, data_date \`\`\``"
/> -->
<MarkdownRender <MarkdownRender
ref="markdownRenderRef" ref="markdownRenderRef"
:raw-text-content=" :raw-text-content="
messageItem.content ? messageItem.content : t('common_module.dialogue_module.empty_message_content') messageItem.content ? messageItem.content : t('common_module.dialogue_module.empty_message_content')
" "
:color="currentBubbleTextColor" :color="currentBubbleTextColor"
:dark-theme="false"
/> />
<div v-if="messageItem.isAnswerLoading" class="ml-[15px] pt-[12px]"> <div v-if="messageItem.isAnswerLoading" class="ml-[15px] pt-[12px]">
...@@ -184,6 +147,15 @@ const handleContentEdit = throttle( ...@@ -184,6 +147,15 @@ const handleContentEdit = throttle(
</span> </span>
</div> </div>
</div> </div>
<SmartForms
v-else
type="BusinessTripForm"
:message-author="messageAuthor"
:is-agent-message="isAgentMessage"
:message-item="messageItem"
:current-bubble-text-color="currentBubbleTextColor"
/>
</div> </div>
</div> </div>
</template> </template>
......
<script setup lang="ts">
import { readonly, ref, useTemplateRef } from 'vue'
import type { MessageItemInterface } from '../../types'
import MarkdownRender from '@/components/markdown-render/markdown-render.vue'
import type { FormInst, FormRules } from 'naive-ui'
import { useI18n } from 'vue-i18n'
import { useSystemLanguageStore } from '@/store/modules/system-language'
interface Props {
isAgentMessage: boolean
messageItem: MessageItemInterface
currentBubbleTextColor: string
messageAuthor: string
}
defineProps<Props>()
const { t } = useI18n()
const systemLanguageStore = useSystemLanguageStore()
const businessTripFormRef = useTemplateRef<FormInst>('businessTripFormRef')
const formRules = readonly<FormRules>({
objective: {
required: true,
trigger: ['blur', 'input'],
message: '',
},
travelLocation: {
required: true,
trigger: ['blur', 'input'],
message: '',
},
departureTime: {
type: 'number',
required: true,
trigger: ['blur', 'input'],
message: '',
},
returnTime: {
type: 'number',
required: true,
trigger: ['blur', 'input'],
message: '',
},
email: {
required: true,
trigger: ['blur', 'input'],
message: '',
},
})
const formModel = ref({
objective: 'khbf',
travelLocation: '',
departureTime: null,
returnTime: null,
vehicle: '',
vehicleEstimatedCost: '',
residence: '',
residenceEstimatedCost: '',
estimatedAmount: '',
generalBudget: '',
email: '',
})
const objectiveOptions = readonly([
{
label: '客户拜访',
value: 'khbf',
},
{
label: '会议',
value: 'hy',
},
{
label: '培训',
value: 'px',
},
])
const isDisabledForm = ref(false)
function switchFormDisabledStatus() {
isDisabledForm.value = !isDisabledForm.value
}
function handleSubmitForm() {
businessTripFormRef.value?.validate((errors) => {
if (!errors) {
window.$message.success('提交')
}
})
}
defineExpose({
switchFormDisabledStatus,
})
</script>
<template>
<div class="ml-[11px] overflow-hidden">
<div class="mb-[7px] text-[12px] text-[#999]">{{ messageAuthor }}</div>
<div
:class="{
'min-w-[420px]': !systemLanguageStore.isEnglishLanguage,
'min-w-[500px]': systemLanguageStore.isEnglishLanguage,
}"
>
<div
class="box-content min-h-[21px] min-w-[10px] max-w-full rounded-[10px] border border-[#9EA3FF] bg-[#777EF9] px-[15px] py-[14px] text-justify"
:class="{
'!bg-[#fff]': isAgentMessage,
'!min-w-[80px]': messageItem.isAnswerLoading,
}"
>
<div
v-if="messageItem.isAnswerLoading && !messageItem.content"
class="flex h-[21px] items-center justify-center"
>
<MessageBubbleLoading :active-color="currentBubbleTextColor" />
</div>
<template v-else>
<div class="mb-[10px]">
<i class="iconfont icon-tongyi font-600 text-[14px] text-[#6ccb59]"></i>
<span class="ml-[5px] text-[14px] text-[#999]">{{
t('smart_forms_module.business_trip_form.execution_successful_doc')
}}</span>
</div>
<MarkdownRender
ref="markdownRenderRef"
raw-text-content="好的,我将为您自动生成出差表单,表单如下"
:color="currentBubbleTextColor"
/>
<!-- <div v-if="messageItem.isAnswerLoading" class="ml-[15px] pt-[12px]">
<MessageBubbleLoading active-color="#fff" width="5px" />
</div> -->
</template>
</div>
<div
class="mt-[10px] box-content min-h-[21px] min-w-[10px] max-w-full rounded-[10px] border border-[#9EA3FF] bg-[#777EF9] px-[15px] py-[14px] text-justify"
:class="{
'!bg-[#fff]': isAgentMessage,
}"
>
<h2 class="font-600 text-[15px] text-[#0B7DFF]">{{ t('smart_forms_module.business_trip_form.title') }}</h2>
<div class="mt-[12px]">
<n-form
ref="businessTripFormRef"
:model="formModel"
:rules="formRules"
label-placement="left"
:label-width="systemLanguageStore.isEnglishLanguage ? '150' : '90'"
require-mark-placement="right-hanging"
:show-feedback="false"
:disabled="isDisabledForm"
>
<n-form-item
class="mb-[10px]"
:label="t('smart_forms_module.business_trip_form.objective')"
path="objective"
>
<n-select
v-model:value="formModel.objective"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')}${t('smart_forms_module.business_trip_form.objective')}`"
:options="objectiveOptions"
/>
</n-form-item>
<n-form-item
class="mb-[10px]"
:label="t('smart_forms_module.business_trip_form.travel_location')"
path="travelLocation"
>
<n-input
v-model:value="formModel.travelLocation"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')} ${t('smart_forms_module.business_trip_form.objective').toLocaleLowerCase()}`"
/>
</n-form-item>
<n-form-item
class="mb-[10px]"
:label="t('smart_forms_module.business_trip_form.departure_time')"
path="departureTime"
>
<n-date-picker v-model:value="formModel.departureTime" type="datetime" />
</n-form-item>
<n-form-item :label="t('smart_forms_module.business_trip_form.return_time')" path="returnTime">
<n-date-picker v-model:value="formModel.returnTime" type="datetime" />
</n-form-item>
<n-form-item label="">
<div class="h-[1px] w-full bg-[#B1B1B1] opacity-45"></div>
</n-form-item>
<n-form-item class="mb-[10px]" :label="t('smart_forms_module.business_trip_form.vehicle')" path="vehicle">
<n-input
v-model:value="formModel.vehicle"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')} ${t('smart_forms_module.business_trip_form.vehicle').toLocaleLowerCase()}`"
/>
</n-form-item>
<n-form-item :label="t('smart_forms_module.business_trip_form.estimated_cost')" path="vehicleEstimatedCost">
<n-input
v-model:value="formModel.vehicleEstimatedCost"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')} ${t('smart_forms_module.business_trip_form.estimated_cost').toLocaleLowerCase()}`"
/>
</n-form-item>
<n-form-item label="">
<div class="h-[1px] w-full bg-[#B1B1B1] opacity-45"></div>
</n-form-item>
<n-form-item
class="mb-[10px]"
:label="t('smart_forms_module.business_trip_form.residence')"
path="residence"
>
<n-input
v-model:value="formModel.residence"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')} ${t('smart_forms_module.business_trip_form.residence').toLocaleLowerCase()}`"
/>
</n-form-item>
<n-form-item
:label="t('smart_forms_module.business_trip_form.estimated_cost')"
path="residenceEstimatedCost"
>
<n-input
v-model:value="formModel.residenceEstimatedCost"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')} ${t('smart_forms_module.business_trip_form.estimated_cost').toLocaleLowerCase()}`"
/>
</n-form-item>
<n-form-item label="">
<div class="h-[1px] w-full bg-[#B1B1B1] opacity-45"></div>
</n-form-item>
<n-form-item
class="mb-[10px]"
:label="t('smart_forms_module.business_trip_form.estimated_amount')"
path="estimatedAmount"
>
<n-input
v-model:value="formModel.estimatedAmount"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')} ${t('smart_forms_module.business_trip_form.estimated_amount').toLocaleLowerCase()}`"
/>
</n-form-item>
<n-form-item :label="t('smart_forms_module.business_trip_form.general_budget')" path="generalBudget">
<n-input
v-model:value="formModel.generalBudget"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')} ${t('smart_forms_module.business_trip_form.general_budget').toLocaleLowerCase()}`"
/>
</n-form-item>
<n-form-item label="">
<div class="h-[1px] w-full bg-[#B1B1B1] opacity-45"></div>
</n-form-item>
<n-form-item class="mb-[10px]" :label="t('smart_forms_module.business_trip_form.email')" path="email">
<n-input
v-model:value="formModel.email"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')} ${t('smart_forms_module.business_trip_form.email').toLocaleLowerCase()}`"
/>
</n-form-item>
<div class="mt-[30px] text-end">
<n-button type="primary" :disabled="isDisabledForm" @click="handleSubmitForm">
{{ t('smart_forms_module.business_trip_form.confirm_submission') }}
</n-button>
</div>
</n-form>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { readonly, ref } from 'vue'
import type { MessageItemInterface } from '../../types'
import MarkdownRender from '@/components/markdown-render/markdown-render.vue'
import type { FormRules } from 'naive-ui'
import MessageBubbleLoading from '../message-bubble-loading.vue'
interface Props {
isAgentMessage: boolean
messageItem: MessageItemInterface
currentBubbleTextColor: string
}
defineProps<Props>()
const formRules = readonly<FormRules>({
objective: {
required: true,
trigger: ['blur', 'input'],
message: '',
},
travelLocation: {
required: true,
trigger: ['blur', 'input'],
message: '',
},
departureTime: {
required: true,
trigger: ['blur', 'input'],
message: '',
},
returnTime: {
required: true,
trigger: ['blur', 'input'],
message: '',
},
email: {
required: true,
trigger: ['blur', 'input'],
message: '',
},
})
const formModel = ref({
objective: 'khbf',
travelLocation: '',
departureTime: null,
returnTime: null,
vehicle: '',
vehicleEstimatedCost: '',
residence: '',
residenceEstimatedCost: '',
estimatedAmount: '',
generalBudget: '',
email: '',
})
const objectiveOptions = readonly([
{
label: '客户拜访',
value: 'khbf',
},
{
label: '会议',
value: 'hy',
},
{
label: '培训',
value: 'px',
},
])
</script>
<template>
<div class="ml-[11px] overflow-hidden">
<div class="mb-[7px] text-[12px] text-[#999]">作者信息</div>
<div class="min-w-[420px]">
<div
class="box-content min-h-[21px] min-w-[10px] max-w-full rounded-[10px] border border-[#9EA3FF] bg-[#777EF9] px-[15px] py-[14px] text-justify"
:class="{
'!bg-[#fff]': isAgentMessage,
'!min-w-[80px]': messageItem.isAnswerLoading,
}"
>
<div
v-if="messageItem.isAnswerLoading && !messageItem.content"
class="flex h-[21px] items-center justify-center"
>
<MessageBubbleLoading :active-color="currentBubbleTextColor" />
</div>
<template v-else>
<div class="mb-[10px]">
<i class="iconfont icon-tongyi font-600 text-[14px] text-[#6ccb59]"></i>
<span class="ml-[5px] text-[14px] text-[#999]">出差表单插件执行成功</span>
</div>
<MarkdownRender
ref="markdownRenderRef"
raw-text-content="好的,我将为您自动生成出差表单,表单如下"
:color="currentBubbleTextColor"
/>
<!-- <div v-if="messageItem.isAnswerLoading" class="ml-[15px] pt-[12px]">
<MessageBubbleLoading active-color="#fff" width="5px" />
</div> -->
</template>
</div>
<div
class="mt-[10px] box-content min-h-[21px] min-w-[10px] max-w-full rounded-[10px] border border-[#9EA3FF] bg-[#777EF9] px-[15px] py-[14px] text-justify"
:class="{
'!bg-[#fff]': isAgentMessage,
}"
>
<h2 class="font-600 text-[15px] text-[#0B7DFF]">出差表单</h2>
<div class="mt-[12px]">
<n-form :model="formModel" :rules="formRules" label-width="90" label-placement="left" :show-feedback="false">
<n-form-item class="mb-[10px]" label="出差目的" path="objective">
<n-select v-model:value="formModel.objective" placeholder="Select" :options="objectiveOptions" />
</n-form-item>
<n-form-item class="mb-[10px]" label="出差地点" path="travelLocation">
<n-input v-model:value="formModel.travelLocation" placeholder="Input" />
</n-form-item>
<n-form-item class="mb-[10px]" label="出发时间" path="departureTime">
<n-date-picker v-model:value="formModel.departureTime" type="datetime" />
</n-form-item>
<n-form-item label="返回时间" path="returnTime">
<n-date-picker v-model:value="formModel.returnTime" type="datetime" />
</n-form-item>
<n-form-item label="">
<div class="h-[1px] w-full bg-[#B1B1B1] opacity-45"></div>
</n-form-item>
<n-form-item class="mb-[10px]" label="交通工具" path="vehicle">
<n-input v-model:value="formModel.vehicle" placeholder="Input" />
</n-form-item>
<n-form-item label="预计费用" path="vehicleEstimatedCost">
<n-input v-model:value="formModel.vehicleEstimatedCost" placeholder="Input" />
</n-form-item>
<n-form-item label="">
<div class="h-[1px] w-full bg-[#B1B1B1] opacity-45"></div>
</n-form-item>
<n-form-item class="mb-[10px]" label="住宿地点" path="residence">
<n-input v-model:value="formModel.residence" placeholder="Input" />
</n-form-item>
<n-form-item label="预计费用" path="residenceEstimatedCost">
<n-input v-model:value="formModel.residenceEstimatedCost" placeholder="Input" />
</n-form-item>
<n-form-item label="">
<div class="h-[1px] w-full bg-[#B1B1B1] opacity-45"></div>
</n-form-item>
<n-form-item class="mb-[10px]" label="预计金额" path="residence">
<n-input v-model:value="formModel.estimatedAmount" placeholder="Input" />
</n-form-item>
<n-form-item label="总预算" path="generalBudget">
<n-input v-model:value="formModel.generalBudget" placeholder="Input" />
</n-form-item>
<n-form-item label="">
<div class="h-[1px] w-full bg-[#B1B1B1] opacity-45"></div>
</n-form-item>
<n-form-item class="mb-[10px]" label="邮箱信息" path="email">
<n-input v-model:value="formModel.email" placeholder="Input" />
</n-form-item>
<div class="mt-[30px] text-end">
<n-button type="primary">确认提交</n-button>
</div>
</n-form>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useTemplateRef } from 'vue'
import type { MessageItemInterface, SmartFormTypes } from '../../types'
import BusinessTripForm from './business-trip-form.vue'
// import BusinessTripReimbursementForm from './business-trip-reimbursement-form.vue'
interface Props {
type: SmartFormTypes
isAgentMessage: boolean
messageAuthor: string
messageItem: MessageItemInterface
currentBubbleTextColor: string
}
defineProps<Props>()
const businessTripFormRefList = useTemplateRef<InstanceType<typeof BusinessTripForm>>('businessTripFormComRef')
defineExpose({
businessTripFormRefList,
})
</script>
<template>
<BusinessTripForm
ref="businessTripFormComRef"
:is-agent-message="isAgentMessage"
:message-item="messageItem"
:message-author="messageAuthor"
:current-bubble-text-color="currentBubbleTextColor"
/>
<!-- <BusinessTripReimbursementForm
:is-agent-message="isAgentMessage"
:message-item="messageItem"
:current-bubble-text-color="currentBubbleTextColor"
/> -->
</template>
...@@ -22,3 +22,5 @@ export interface MessageItemInterface { ...@@ -22,3 +22,5 @@ export interface MessageItemInterface {
imageUrl?: string imageUrl?: string
reasoningContent: string reasoningContent: string
} }
export type SmartFormTypes = 'BusinessTripForm'
...@@ -875,5 +875,24 @@ declare namespace I18n { ...@@ -875,5 +875,24 @@ declare namespace I18n {
concise_and_clear: string concise_and_clear: string
elegant_literary_style: string elegant_literary_style: string
} }
smart_forms_module: {
business_trip_form: {
title: string
objective: string
travel_location: string
departure_time: string
return_time: string
vehicle: string
estimated_cost: string
residence: string
estimated_amount: string
general_budget: string
email: string
confirm_submission: string
please_enter_the: string
execution_successful_doc: string
}
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment