Commit b9488cdb authored by tyyin lan's avatar tyyin lan

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

parent 32a99e0e
...@@ -873,3 +873,6 @@ smart_forms_module: ...@@ -873,3 +873,6 @@ smart_forms_module:
confirm_submission: 'Confirm submission' confirm_submission: 'Confirm submission'
please_enter_the: 'Please enter the' please_enter_the: 'Please enter the'
execution_successful_doc: 'Execution successful doc' execution_successful_doc: 'Execution successful doc'
customer_visit: 'Customer visit'
meeting: 'Meeting'
training: 'Training'
...@@ -871,3 +871,6 @@ smart_forms_module: ...@@ -871,3 +871,6 @@ smart_forms_module:
confirm_submission: '确认提交' confirm_submission: '确认提交'
please_enter_the: '请输入' please_enter_the: '请输入'
execution_successful_doc: '出差表单插件执行成功' execution_successful_doc: '出差表单插件执行成功'
customer_visit: '客户拜访'
meeting: '会议'
training: '培训'
...@@ -871,3 +871,6 @@ smart_forms_module: ...@@ -871,3 +871,6 @@ smart_forms_module:
confirm_submission: '確認提交' confirm_submission: '確認提交'
please_enter_the: '請輸入' please_enter_the: '請輸入'
execution_successful_doc: '出差表單插件執行成功' execution_successful_doc: '出差表單插件執行成功'
customer_visit: '客戶拜訪'
meeting: '會議'
training: '培訓'
<script setup lang="ts"> <script setup lang="ts">
import { computed, readonly, useTemplateRef } from 'vue' import { computed, provide, readonly, useTemplateRef } from 'vue'
import { CheckOne } 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'
...@@ -14,6 +14,7 @@ import AuthorInfo from './author-info.vue' ...@@ -14,6 +14,7 @@ import AuthorInfo from './author-info.vue'
interface Props { interface Props {
messageItem: MessageItemInterface messageItem: MessageItemInterface
messageItemId: string
} }
const props = defineProps<Props>() const props = defineProps<Props>()
...@@ -26,6 +27,8 @@ const userStore = useUserStore() ...@@ -26,6 +27,8 @@ const userStore = useUserStore()
const markdownRenderRef = useTemplateRef<InstanceType<typeof MarkdownRender>>('markdownRenderRef') const markdownRenderRef = useTemplateRef<InstanceType<typeof MarkdownRender>>('markdownRenderRef')
provide('messageItemId', props.messageItemId)
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 isAgentMessage = computed(() => { const isAgentMessage = computed(() => {
...@@ -150,10 +153,9 @@ const handleContentEdit = throttle( ...@@ -150,10 +153,9 @@ const handleContentEdit = throttle(
<SmartForms <SmartForms
v-else v-else
type="BusinessTripForm" :message-item="messageItem"
:message-author="messageAuthor" :message-author="messageAuthor"
:is-agent-message="isAgentMessage" :is-agent-message="isAgentMessage"
:message-item="messageItem"
:current-bubble-text-color="currentBubbleTextColor" :current-bubble-text-color="currentBubbleTextColor"
/> />
</div> </div>
......
<script setup lang="ts"> <script setup lang="ts">
import MessageItem from './message-item.vue' import MessageItem from './message-item.vue'
import type { MessageItemInterface } from '../types' import type { MessageItemInterface } from '../types'
import { ref, useTemplateRef } from 'vue' import { provide, ref, useTemplateRef } from 'vue'
import { ScrollbarInst } from 'naive-ui' import { ScrollbarInst } from 'naive-ui'
import EditorDrawer from '@/components/editor-drawer/editor-drawer.vue' import EditorDrawer from '@/components/editor-drawer/editor-drawer.vue'
import { useElementVisibility } from '@vueuse/core' import { useElementVisibility } from '@vueuse/core'
...@@ -12,12 +12,21 @@ interface Props { ...@@ -12,12 +12,21 @@ interface Props {
} }
defineProps<Props>() defineProps<Props>()
const emit = defineEmits<{
updateSpecifyMessageItem: [messageId: string, newMessageItem: Partial<MessageItemInterface>]
}>()
const scrollbarRef = useTemplateRef<ScrollbarInst | null>('scrollbarRef') const scrollbarRef = useTemplateRef<ScrollbarInst | null>('scrollbarRef')
const backBottomBtnFlagRef = useTemplateRef<HTMLDivElement | null>('backBottomBtnFlagRef') const backBottomBtnFlagRef = useTemplateRef<HTMLDivElement | null>('backBottomBtnFlagRef')
const isNotShowBackBottomBtn = useElementVisibility(backBottomBtnFlagRef) const isNotShowBackBottomBtn = useElementVisibility(backBottomBtnFlagRef)
provide('updateSpecifyMessageItem', {
updateSpecifyMessageItem: (messageId: string, newMessageItem: Partial<MessageItemInterface>) => {
emit('updateSpecifyMessageItem', messageId, newMessageItem)
},
})
const isShowEditorDrawer = ref(false) const isShowEditorDrawer = ref(false)
const contentEdit = ref('') const contentEdit = ref('')
...@@ -50,6 +59,7 @@ defineExpose({ ...@@ -50,6 +59,7 @@ defineExpose({
<MessageItem <MessageItem
v-for="[key, messageItem] in messageList" v-for="[key, messageItem] in messageList"
:key="key" :key="key"
:message-item-id="key"
:message-item="messageItem" :message-item="messageItem"
@contentedit="onContentedit" @contentedit="onContentedit"
/> />
......
<script setup lang="ts"> <script setup lang="ts">
import { readonly, ref, useTemplateRef } from 'vue' import { computed, inject, readonly, ref, useTemplateRef } from 'vue'
import type { MessageItemInterface } from '../../types' import type { MessageItemInterface } from '../../types'
import MarkdownRender from '@/components/markdown-render/markdown-render.vue' import MarkdownRender from '@/components/markdown-render/markdown-render.vue'
import type { FormInst, FormRules } from 'naive-ui' import type { FormInst, FormRules, FormItemRule } from 'naive-ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useSystemLanguageStore } from '@/store/modules/system-language' import { useSystemLanguageStore } from '@/store/modules/system-language'
import MessageBubbleLoading from '../message-bubble-loading.vue'
import isEmail from 'validator/es/lib/isEmail'
interface Props { interface Props {
isAgentMessage: boolean
messageItem: MessageItemInterface messageItem: MessageItemInterface
isAgentMessage: boolean
currentBubbleTextColor: string currentBubbleTextColor: string
messageAuthor: string messageAuthor: string
} }
defineProps<Props>() const props = defineProps<Props>()
const { t } = useI18n() const { t } = useI18n()
const systemLanguageStore = useSystemLanguageStore() const systemLanguageStore = useSystemLanguageStore()
const businessTripFormRef = useTemplateRef<FormInst>('businessTripFormRef') const businessTripFormRef = useTemplateRef<FormInst>('businessTripFormRef')
const messageItemId = inject('messageItemId', '')
const { updateSpecifyMessageItem } = inject<{
updateSpecifyMessageItem: (messageId: string, newMessageItem: Partial<MessageItemInterface>) => void
}>('updateSpecifyMessageItem', {
updateSpecifyMessageItem: () => {},
})
const formRules = readonly<FormRules>({ const formRules = readonly<FormRules>({
objective: { objective: {
required: true, required: true,
...@@ -46,12 +55,20 @@ const formRules = readonly<FormRules>({ ...@@ -46,12 +55,20 @@ const formRules = readonly<FormRules>({
email: { email: {
required: true, required: true,
trigger: ['blur', 'input'], trigger: ['blur', 'input'],
message: '', validator: (_rule: FormItemRule, value: string) => {
if (!value) {
return new Error(t('login_module.please_enter_your_email_address'))
} else if (!isEmail(value)) {
return new Error(t('login_module.please_enter_the_correct_email_address'))
}
return
},
}, },
}) })
const formModel = ref({ const formModel = ref({
objective: 'khbf', objective: 'CustomerVisits',
travelLocation: '', travelLocation: '',
departureTime: null, departureTime: null,
returnTime: null, returnTime: null,
...@@ -66,36 +83,37 @@ const formModel = ref({ ...@@ -66,36 +83,37 @@ const formModel = ref({
const objectiveOptions = readonly([ const objectiveOptions = readonly([
{ {
label: '客户拜访', label: t('smart_forms_module.business_trip_form.customer_visit'),
value: 'khbf', value: 'CustomerVisits',
}, },
{ {
label: '会议', label: t('smart_forms_module.business_trip_form.meeting'),
value: 'hy', value: 'Meetings',
}, },
{ {
label: '培训', label: t('smart_forms_module.business_trip_form.training'),
value: 'px', value: 'Training',
}, },
]) ])
const isDisabledForm = ref(false) const isDisabledForm = computed(() => {
return !!props.messageItem.smartFormInfo && props.messageItem.smartFormInfo.isDisabled
function switchFormDisabledStatus() { })
isDisabledForm.value = !isDisabledForm.value
}
function handleSubmitForm() { function handleSubmitForm() {
businessTripFormRef.value?.validate((errors) => { businessTripFormRef.value?.validate((errors) => {
if (!errors) { if (!errors) {
window.$message.success('提交') window.$message.success('提交')
updateSpecifyMessageItem(messageItemId, {
smartFormInfo: {
...(props.messageItem.smartFormInfo || { type: 'BusinessTripForm', params: '' }),
isDisabled: true,
},
})
} }
}) })
} }
defineExpose({
switchFormDisabledStatus,
})
</script> </script>
<template> <template>
...@@ -271,7 +289,7 @@ defineExpose({ ...@@ -271,7 +289,7 @@ defineExpose({
/> />
</n-form-item> </n-form-item>
<div class="mt-[30px] text-end"> <div class="mt-[46px] text-end">
<n-button type="primary" :disabled="isDisabledForm" @click="handleSubmitForm"> <n-button type="primary" :disabled="isDisabledForm" @click="handleSubmitForm">
{{ t('smart_forms_module.business_trip_form.confirm_submission') }} {{ t('smart_forms_module.business_trip_form.confirm_submission') }}
</n-button> </n-button>
......
<script setup lang="ts"> <script setup lang="ts">
import { useTemplateRef } from 'vue' import type { MessageItemInterface } from '../../types'
import type { MessageItemInterface, SmartFormTypes } from '../../types'
import BusinessTripForm from './business-trip-form.vue' import BusinessTripForm from './business-trip-form.vue'
// import BusinessTripReimbursementForm from './business-trip-reimbursement-form.vue' // import BusinessTripReimbursementForm from './business-trip-reimbursement-form.vue'
interface Props { interface Props {
type: SmartFormTypes
isAgentMessage: boolean isAgentMessage: boolean
messageAuthor: string messageAuthor: string
messageItem: MessageItemInterface messageItem: MessageItemInterface
...@@ -13,19 +11,12 @@ interface Props { ...@@ -13,19 +11,12 @@ interface Props {
} }
defineProps<Props>() defineProps<Props>()
const businessTripFormRefList = useTemplateRef<InstanceType<typeof BusinessTripForm>>('businessTripFormComRef')
defineExpose({
businessTripFormRefList,
})
</script> </script>
<template> <template>
<BusinessTripForm <BusinessTripForm
ref="businessTripFormComRef"
:is-agent-message="isAgentMessage"
:message-item="messageItem" :message-item="messageItem"
:is-agent-message="isAgentMessage"
:message-author="messageAuthor" :message-author="messageAuthor"
:current-bubble-text-color="currentBubbleTextColor" :current-bubble-text-color="currentBubbleTextColor"
/> />
......
...@@ -44,32 +44,35 @@ const isShowMessageList = ref(false) ...@@ -44,32 +44,35 @@ const isShowMessageList = ref(false)
const isAgentInitLoading = ref(true) const isAgentInitLoading = ref(true)
const currentFetchEventSourceController = ref<AbortController | null>(null) const currentFetchEventSourceController = ref<AbortController | null>(null)
// setTimeout(() => { /* setTimeout(() => {
// messageList.value.set('1', { messageList.value.set('1', {
// role: 'user', role: 'assistant',
// agentId: 'b058f1baedd04af983ca00775368bb8c', agentId: 'b058f1baedd04af983ca00775368bb8c',
// content: '请推荐一些适合初学者的编程学习资源。', content: '请推荐一些适合初学者的编程学习资源。',
// timestamp: 1726654820427, timestamp: 1726654820427,
// isAnswerLoading: false, isAnswerLoading: false,
// avatar: 'http://localhost:8848/fe/src/assets/images/home/agent-avatar.png', avatar: 'http://localhost:8848/fe/src/assets/images/home/agent-avatar.png',
// name: '1234', name: '我是作者',
// reasoningContent: '1324', reasoningContent: '1324',
// imageUrl: '', imageUrl: '',
// pluginName: '', pluginName: '',
// }) smartFormInfo: { type: 'BusinessTripForm', isDisabled: true, params: '' },
// }, 60) })
// messageList.value.set('2', {
// role: 'assistant', messageList.value.set('2', {
// agentId: 'b058f1baedd04af983ca00775368bb8c', role: 'assistant',
// content: agentId: 'b058f1baedd04af983ca00775368bb8c',
// '对于初学者的编程学习资源,可以从以下几个方面进行推荐:\n\n### 一、在线教程与网站\n\n1. **w3school**:这是一个非常全面的编程学习网站,提供了从基础到高级的教程,包括HTML、CSS、JavaScript、SQL等,适合初学者逐步深入学习。\n2. **慕课网**:慕课网上有许多免费课程,涵盖了前端、后端开发,移动开发等多个方面,初学者可以根据自己的兴趣选择相应的课程。\n3. **Coursera**:该网站提供世界名校的网络公开课程,其中也包括计算机编程的相关课程,初学者可以接触到国际一流的教学资源。\n\n### 二、书籍推荐\n\n1. **《Python编程快速上手》**:这本书是为零基础读者打造的Python入门书籍,内容系统且详细,每个知识点都深入浅出,非常适合初学者。\n2. **《C++ Primer Plus》**:这本书是C++语言学习的理想图书,通过大量短小精悍的程序详细阐述了C++的基本概念和技术,对初学者极为友好。\n\n### 三、实践项目与刷题网站\n\n1. **Stack Overflow**:这是一个程序设计领域的问答网站,初学者在遇到编程难题时可以在这里寻找解决方案,同时也可以学习到其他技术大牛的经验和技巧。\n2. **GitHub**:作为全球最大的开源代码托管仓库,GitHub上有无穷无尽的开源代码供初学者学习和参考,阅读源码是一个快速提升编程能力的好方法。\n\n### 四、社区与论坛\n\n1. **CSDN软件开发网**:这是国内知名的软件开发社区,提供了大量的编程资源和经验分享,初学者可以在这里交流学习心得,获取最新的技术动态。\n\n综上所述,初学者可以根据自己的学习需求和兴趣选择合适的编程学习资源。从在线教程、书籍阅读到实践项目和社区交流,多方面的学习将有助于初学者快速掌握编程技能并不断提升自己。', content: '请推荐一些适合初学者的编程学习资源。',
// timestamp: 1726654851735, timestamp: 1726654820427,
// isAnswerLoading: false, isAnswerLoading: false,
// avatar: 'http://localhost:8848/fe/src/assets/images/home/agent-avatar.png', avatar: 'http://localhost:8848/fe/src/assets/images/home/agent-avatar.png',
// name: 'lisa', name: '我是作者',
// reasoningContent: reasoningContent: '1324',
// '对于初学者的编程学习资源,可以从以下几个方面进行推荐:\n\n### 一、在线教程与网站\n\n1. **w3school**:这是一个非常全面的编程学习网站,提供了从基础到高级的教程,包括HTML、CSS、JavaScript、SQL等,适合初学者逐步深入学习。\n2. **慕课网**:慕课网上有许多免费课程,涵盖了前端、后端开发,移动开发等多个方面,初学者可以根据自己的兴趣选择相应的课程。\n3. **Coursera**:该网站提供世界名校的网络公开课程,其中也包括计算机编程的相关课程,初学者可以接触到国际一流的教学资源。\n\n### 二、书籍推荐\n\n1. **《Python编程快速上手》**:这本书是为零基础读者打造的Python入门书籍,内容系统且详细,每个知识点都深入浅出,非常适合初学者。\n2. **《C++ Primer Plus》**:这本书是C++语言学习的理想图书,通过大量短小精悍的程序详细阐述了C++的基本概念和技术,对初学者极为友好。\n\n### 三、实践项目与刷题网站\n\n1. **Stack Overflow**:这是一个程序设计领域的问答网站,初学者在遇到编程难题时可以在这里寻找解决方案,同时也可以学习到其他技术大牛的经验和技巧。\n2. **GitHub**:作为全球最大的开源代码托管仓库,GitHub上有无穷无尽的开源代码供初学者学习和参考,阅读源码是一个快速提升编程能力的好方法。\n\n### 四、社区与论坛\n\n1. **CSDN软件开发网**:这是国内知名的软件开发社区,提供了大量的编程资源和经验分享,初学者可以在这里交流学习心得,获取最新的技术动态。\n\n综上所述,初学者可以根据自己的学习需求和兴趣选择合适的编程学习资源。从在线教程、书籍阅读到实践项目和社区交流,多方面的学习将有助于初学者快速掌握编程技能并不断提升自己', imageUrl: '',
// }) pluginName: '',
smartFormInfo: { type: 'BusinessTripForm', isDisabled: false, params: '' },
})
}, 60) */
const homeContainerWidthWatchDebounce = debounce((newWidth) => { const homeContainerWidthWatchDebounce = debounce((newWidth) => {
if (newWidth <= 1120) { if (newWidth <= 1120) {
...@@ -124,6 +127,15 @@ function messageListScrollToBottom() { ...@@ -124,6 +127,15 @@ function messageListScrollToBottom() {
} }
function onAddMessageItem(messageId: string, messageItem: MessageItemInterface) { 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
}
})
}
messageList.value.set(messageId, messageItem) messageList.value.set(messageId, messageItem)
} }
...@@ -221,7 +233,12 @@ function onClearSessionReferenceFile() { ...@@ -221,7 +233,12 @@ function onClearSessionReferenceFile() {
:current-agent-application="currentAgentApplication" :current-agent-application="currentAgentApplication"
/> />
<MessageList v-show="isShowMessageList" ref="messageListRef" :message-list="messageList" /> <MessageList
v-show="isShowMessageList"
ref="messageListRef"
:message-list="messageList"
@update-specify-message-item="onUpdateSpecifyMessageItem"
/>
<FooterOperation <FooterOperation
ref="footerOperationRef" ref="footerOperationRef"
......
...@@ -10,6 +10,8 @@ export interface AgentApplicationRecordItem { ...@@ -10,6 +10,8 @@ export interface AgentApplicationRecordItem {
unitIds: string[] unitIds: string[]
} }
export type SmartFormTypes = 'BusinessTripForm'
export interface MessageItemInterface { export interface MessageItemInterface {
role: 'user' | 'assistant' role: 'user' | 'assistant'
agentId: string agentId: string
...@@ -21,6 +23,10 @@ export interface MessageItemInterface { ...@@ -21,6 +23,10 @@ export interface MessageItemInterface {
pluginName?: string pluginName?: string
imageUrl?: string imageUrl?: string
reasoningContent: string reasoningContent: string
// isDisabledSmartForm?: boolean
smartFormInfo?: {
type: SmartFormTypes
isDisabled: boolean
params: string
}
} }
export type SmartFormTypes = 'BusinessTripForm'
import type { SmartFormTypes } from '../types'
export function smartFormTypeConverter(type: 'travelForm'): SmartFormTypes {
switch (type) {
case 'travelForm':
return 'BusinessTripForm'
}
}
...@@ -893,6 +893,9 @@ declare namespace I18n { ...@@ -893,6 +893,9 @@ declare namespace I18n {
confirm_submission: string confirm_submission: string
please_enter_the: string please_enter_the: string
execution_successful_doc: string execution_successful_doc: string
customer_visit: string
meeting: string
training: 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