Commit 092f2b8d authored by tyyin lan's avatar tyyin lan

chore(智能表单): 出差表单功能完善

parent b9488cdb
......@@ -859,6 +859,7 @@ editor_module:
smart_forms_module:
business_trip_form:
result_doc: 'Ok. I will automatically generate a business trip form for you. The form is as follows'
title: 'Business trip form'
objective: 'Objective'
travel_location: 'Travel location'
......@@ -867,7 +868,7 @@ smart_forms_module:
vehicle: 'Vehicle'
estimated_cost: 'Estimated cost'
residence: 'Residence'
estimated_amount: 'Estimated amount'
advance_payment_amount: 'Advance payment amount'
general_budget: 'General budget'
email: 'Email'
confirm_submission: 'Confirm submission'
......
......@@ -857,6 +857,7 @@ editor_module:
smart_forms_module:
business_trip_form:
result_doc: '好的,我将为您自动生成出差表单,表单如下'
title: '出差表单'
objective: '出差目的'
travel_location: '出差地点'
......@@ -865,7 +866,7 @@ smart_forms_module:
vehicle: '交通工具'
estimated_cost: '预计费用'
residence: '住宿地点'
estimated_amount: '预计金额'
advance_payment_amount: '预支金额'
general_budget: '总预算'
email: '邮箱信息'
confirm_submission: '确认提交'
......
......@@ -857,6 +857,7 @@ editor_module:
smart_forms_module:
business_trip_form:
result_doc: '好的,我將為您自動生成出差表單,表單如下'
title: '出差表單'
objective: '出差目的'
travel_location: '出差地點'
......@@ -865,7 +866,7 @@ smart_forms_module:
vehicle: '交通工具'
estimated_cost: '預計費用'
residence: '住宿地點'
estimated_amount: '預計金額'
advance_payment_amount: '預支金額'
general_budget: '總預算'
email: '郵箱信息'
confirm_submission: '確認提交'
......
......@@ -6,6 +6,12 @@ import 'dayjs/locale/zh-cn'
dayjs.extend(utc)
dayjs.extend(timezone)
export function formatDateTime(date: string | number | Date, format: string = 'YYYY-MM-DD HH:mm:ss'): string {
type DateType = string | number | Date
export function formatDateTime(date: DateType, format: string = 'YYYY-MM-DD HH:mm:ss'): string {
return dayjs(date).format(format)
}
export function getDayInst(date: DateType) {
return dayjs(date)
}
......@@ -75,7 +75,7 @@ const handleContentEdit = throttle(
<div class="flex">
<img class="h-[36px] w-[36px] rounded-[6px] object-cover" :src="avatarUrl" alt="Avatar" />
<div v-if="true" class="ml-[11px] overflow-hidden">
<div v-if="false" class="ml-[11px] overflow-hidden">
<AuthorInfo :is-agent-message="isAgentMessage" :message-item="messageItem" :message-author="messageAuthor" />
<div
......
<script setup lang="ts">
import { computed, inject, readonly, ref, useTemplateRef } from 'vue'
import { computed, inject, readonly, ref, useTemplateRef, watch } from 'vue'
import type { MessageItemInterface } from '../../types'
import MarkdownRender from '@/components/markdown-render/markdown-render.vue'
import type { FormInst, FormRules, FormItemRule } from 'naive-ui'
......@@ -7,6 +7,8 @@ import { useI18n } from 'vue-i18n'
import { useSystemLanguageStore } from '@/store/modules/system-language'
import MessageBubbleLoading from '../message-bubble-loading.vue'
import isEmail from 'validator/es/lib/isEmail'
import type { BusinessTripForm, ResponseBusinessTripForm } from './types'
import { businessTripFormParser } from '../../utils/smart-forms'
interface Props {
messageItem: MessageItemInterface
......@@ -67,16 +69,16 @@ const formRules = readonly<FormRules>({
},
})
const formModel = ref({
const formModel = ref<BusinessTripForm>({
objective: 'CustomerVisits',
travelLocation: '',
departureTime: null,
returnTime: null,
vehicle: '',
vehicleEstimatedCost: '',
vehicleEstimatedCost: null,
residence: '',
residenceEstimatedCost: '',
estimatedAmount: '',
residenceEstimatedCost: null,
advancePaymentAmount: null,
generalBudget: '',
email: '',
})
......@@ -100,6 +102,30 @@ const isDisabledForm = computed(() => {
return !!props.messageItem.smartFormInfo && props.messageItem.smartFormInfo.isDisabled
})
watch(
() => props.messageItem.smartFormInfo,
(smartFormInfo) => {
if (smartFormInfo && smartFormInfo.params) {
let config: Partial<ResponseBusinessTripForm> = {}
try {
config = JSON.parse(smartFormInfo.params)
} catch (err) {
throw new Error('Invalid JSON')
}
formModel.value = {
...formModel.value,
...businessTripFormParser(config),
}
}
},
{
once: true,
immediate: true,
},
)
function handleSubmitForm() {
businessTripFormRef.value?.validate((errors) => {
if (!errors) {
......@@ -149,7 +175,7 @@ function handleSubmitForm() {
<MarkdownRender
ref="markdownRenderRef"
raw-text-content="好的,我将为您自动生成出差表单,表单如下"
:raw-text-content="t('smart_forms_module.business_trip_form.result_doc')"
:color="currentBubbleTextColor"
/>
......@@ -225,9 +251,10 @@ function handleSubmitForm() {
</n-form-item>
<n-form-item :label="t('smart_forms_module.business_trip_form.estimated_cost')" path="vehicleEstimatedCost">
<n-input
<n-input-number
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()}`"
clearable
/>
</n-form-item>
......@@ -250,9 +277,10 @@ function handleSubmitForm() {
:label="t('smart_forms_module.business_trip_form.estimated_cost')"
path="residenceEstimatedCost"
>
<n-input
<n-input-number
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()}`"
clearable
/>
</n-form-item>
......@@ -262,12 +290,13 @@ function handleSubmitForm() {
<n-form-item
class="mb-[10px]"
:label="t('smart_forms_module.business_trip_form.estimated_amount')"
path="estimatedAmount"
:label="t('smart_forms_module.business_trip_form.advance_payment_amount')"
path="advancePaymentAmount"
>
<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-input-number
v-model:value="formModel.advancePaymentAmount"
:placeholder="`${t('smart_forms_module.business_trip_form.please_enter_the')} ${t('smart_forms_module.business_trip_form.advance_payment_amount').toLocaleLowerCase()}`"
clearable
/>
</n-form-item>
......@@ -275,6 +304,7 @@ function handleSubmitForm() {
<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()}`"
disabled
/>
</n-form-item>
......
export interface ResponseBusinessTripForm {
purpose: string
place: string
departureDate: string
returnDate: string
vehicle: string
transportationFee: string
accommodation: string
accommodationCost: string
advancePaymentAmount: string
totalBudget: string
}
export interface BusinessTripForm {
objective: string
travelLocation: string
departureTime: number | null
returnTime: number | null
vehicle: string
vehicleEstimatedCost: number | null
residence: string
residenceEstimatedCost: number | null
advancePaymentAmount: number | null
generalBudget: string
email: string
}
......@@ -44,20 +44,20 @@ const isShowMessageList = ref(false)
const isAgentInitLoading = ref(true)
const currentFetchEventSourceController = ref<AbortController | null>(null)
/* setTimeout(() => {
messageList.value.set('1', {
role: 'assistant',
agentId: 'b058f1baedd04af983ca00775368bb8c',
content: '请推荐一些适合初学者的编程学习资源。',
timestamp: 1726654820427,
isAnswerLoading: false,
avatar: 'http://localhost:8848/fe/src/assets/images/home/agent-avatar.png',
name: '我是作者',
reasoningContent: '1324',
imageUrl: '',
pluginName: '',
smartFormInfo: { type: 'BusinessTripForm', isDisabled: true, params: '' },
})
setTimeout(() => {
// messageList.value.set('1', {
// role: 'assistant',
// agentId: 'b058f1baedd04af983ca00775368bb8c',
// content: '请推荐一些适合初学者的编程学习资源。',
// timestamp: 1726654820427,
// isAnswerLoading: false,
// avatar: 'http://localhost:8848/fe/src/assets/images/home/agent-avatar.png',
// name: '我是作者',
// reasoningContent: '1324',
// imageUrl: '',
// pluginName: '',
// smartFormInfo: { type: 'BusinessTripForm', isDisabled: true, params: '' },
// })
messageList.value.set('2', {
role: 'assistant',
......@@ -70,9 +70,35 @@ const currentFetchEventSourceController = ref<AbortController | null>(null)
reasoningContent: '1324',
imageUrl: '',
pluginName: '',
smartFormInfo: { type: 'BusinessTripForm', isDisabled: false, params: '' },
smartFormInfo: {
type: 'BusinessTripForm',
isDisabled: false,
params:
'{"purpose":"Training","place":"香港","departureDate":"returnDate","accommodationCost":"11","departureDate":"2025-05-10 15:00:00","advancePaymentAmount":"11","totalBudget":"11"}',
},
})
}, 60) */
}, 60)
// setTimeout(() => {
// onAddMessageItem('3', {
// role: 'assistant',
// agentId: 'b058f1baedd04af983ca00775368bb8c',
// content: '请推荐一些适合初学者的编程学习资源。',
// timestamp: 1726654820427,
// isAnswerLoading: false,
// avatar: 'http://localhost:8848/fe/src/assets/images/home/agent-avatar.png',
// name: '我是作者',
// reasoningContent: '1324',
// imageUrl: '',
// pluginName: '',
// smartFormInfo: {
// type: 'BusinessTripForm',
// isDisabled: false,
// params:
// '{"purpose":"Training","place":"香港","departureDate":"returnDate","accommodationCost":"11","departureDate":"2025-05-10 15:00:00","advancePaymentAmount":"11","totalBudget":"11"}',
// },
// })
// }, 2000)
const homeContainerWidthWatchDebounce = debounce((newWidth) => {
if (newWidth <= 1120) {
......@@ -131,7 +157,7 @@ function onAddMessageItem(messageId: string, messageItem: MessageItemInterface)
if (messageItem.smartFormInfo && messageItem.smartFormInfo.type) {
messageList.value.forEach((messageInfo) => {
if (messageInfo.smartFormInfo && messageInfo.smartFormInfo.type === messageItem.smartFormInfo?.type) {
messageInfo.smartFormInfo.isDisabled = false
messageInfo.smartFormInfo.isDisabled = true
}
})
}
......
import type { SmartFormTypes } from '../types'
import { ResponseBusinessTripForm, BusinessTripForm } from '@/views/home/components/smart-forms/types'
export function smartFormTypeConverter(type: 'travelForm'): SmartFormTypes {
switch (type) {
......@@ -6,3 +7,34 @@ export function smartFormTypeConverter(type: 'travelForm'): SmartFormTypes {
return 'BusinessTripForm'
}
}
export function businessTripFormParser(resForm: Partial<ResponseBusinessTripForm>) {
return {
objective: resForm.purpose || 'CustomerVisits',
travelLocation: resForm.place || '',
departureTime: resForm.departureDate ? Date.parse(resForm.departureDate) : null,
returnTime: resForm.returnDate ? Date.parse(resForm.returnDate) : null,
vehicle: resForm.vehicle || '',
vehicleEstimatedCost: resForm.transportationFee ? Number.parseInt(resForm.transportationFee) : null,
residence: resForm.accommodation || '',
residenceEstimatedCost: resForm.accommodationCost ? Number.parseInt(resForm.accommodationCost) : null,
advancePaymentAmount: resForm.advancePaymentAmount ? Number.parseInt(resForm.advancePaymentAmount) : null,
generalBudget: resForm.totalBudget || '',
email: '',
}
}
export function businessTripFormReturner(form: BusinessTripForm) {
return {
purpose: form.objective,
place: form.travelLocation,
departureDate: form.departureTime,
returnDate: form.returnTime,
vehicle: form.vehicle,
transportationFee: form.vehicleEstimatedCost,
accommodation: form.residence,
accommodationCost: form.residenceEstimatedCost,
advancePaymentAmount: form.advancePaymentAmount,
totalBudget: form.generalBudget,
}
}
......@@ -879,6 +879,7 @@ declare namespace I18n {
smart_forms_module: {
business_trip_form: {
result_doc: string
title: string
objective: string
travel_location: string
......@@ -887,7 +888,7 @@ declare namespace I18n {
vehicle: string
estimated_cost: string
residence: string
estimated_amount: string
advance_payment_amount: string
general_budget: string
email: string
confirm_submission: 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