Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
poc-fe
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
poc
poc-fe
Commits
daf2a679
Commit
daf2a679
authored
May 09, 2025
by
tyyin lan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 智能表单(出差表单)
parent
6bd7de7c
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
693 additions
and
53 deletions
+693
-53
en.yaml
src/locales/langs/en.yaml
+17
-0
zh-cn.yaml
src/locales/langs/zh-cn.yaml
+17
-0
zh-hk.yaml
src/locales/langs/zh-hk.yaml
+17
-0
system-language.ts
src/store/modules/system-language.ts
+3
-0
author-info.vue
src/views/home/components/author-info.vue
+83
-0
message-item.vue
src/views/home/components/message-item.vue
+25
-53
business-trip-form.vue
src/views/home/components/smart-forms/business-trip-form.vue
+284
-0
business-trip-reimbursement-form.vue
...mponents/smart-forms/business-trip-reimbursement-form.vue
+188
-0
index.vue
src/views/home/components/smart-forms/index.vue
+38
-0
types.d.ts
src/views/home/types.d.ts
+2
-0
locales.d.ts
types/locales.d.ts
+19
-0
No files found.
src/locales/langs/en.yaml
View file @
daf2a679
...
@@ -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'
src/locales/langs/zh-cn.yaml
View file @
daf2a679
...
@@ -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
:
'
出差表单插件执行成功'
src/locales/langs/zh-hk.yaml
View file @
daf2a679
...
@@ -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
:
'
出差表單插件執行成功'
src/store/modules/system-language.ts
View file @
daf2a679
...
@@ -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
)
{
...
...
src/views/home/components/author-info.vue
0 → 100644
View file @
daf2a679
<
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
>
src/views/home/components/message-item.vue
View file @
daf2a679
<
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>
...
...
src/views/home/components/smart-forms/business-trip-form.vue
0 → 100644
View file @
daf2a679
<
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>
src/views/home/components/smart-forms/business-trip-reimbursement-form.vue
0 → 100644
View file @
daf2a679
<
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>
src/views/home/components/smart-forms/index.vue
0 → 100644
View file @
daf2a679
<
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
>
src/views/home/types.d.ts
View file @
daf2a679
...
@@ -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'
types/locales.d.ts
View file @
daf2a679
...
@@ -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
}
}
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment