Commit 1731e7c4 authored by shirlyn.guo's avatar shirlyn.guo 🤡

feat: 声音与数字人形象定制

parent 68da53a5
<script setup lang="ts">
import type { FormInst, FormItemRule, FormRules } from 'naive-ui'
import { ref, shallowReadonly, useTemplateRef } from 'vue'
import isMobilePhone from 'validator/es/lib/isMobilePhone'
import isEmail from 'validator/es/lib/isEmail'
const isShowVoiceCharacterCustomizeModal = defineModel<boolean>('isShowVoiceCharacterCustomizeModal', {
default: false,
})
const customizeInfoFormRef = useTemplateRef<FormInst>('customizeInfoFormRef')
const customizeInfoForm = ref({
companyName: '',
contactsName: '',
contactInformation: '',
})
const customizeInfoFormRules = shallowReadonly<FormRules>({
companyName: {
required: true,
trigger: 'blur',
validator: (_rule: FormItemRule, value: string) => {
if (!value) {
return new Error('請填寫公司名稱')
}
if (value.length > 50) {
return new Error('公司名稱不能超過50個字')
}
return
},
},
contactsName: {
required: true,
trigger: 'blur',
validator: (_rule: FormItemRule, value: string) => {
if (!value) {
return new Error('請填寫聯繫人姓名')
}
if (value.length > 50) {
return new Error('聯繫人姓名不能超過50個字')
}
return
},
},
contactInformation: {
required: true,
trigger: 'blur',
validator: (_rule: FormItemRule, value: string) => {
if (!value) {
return new Error('請填寫聯繫方式')
}
const hasAreaCode = value.startsWith('+86') || value.startsWith('+852')
const isPhoneValid = isMobilePhone(value, ['zh-CN', 'zh-HK'])
const isEmailValid = isEmail(value)
if (isPhoneValid && !hasAreaCode) {
return new Error('手機號碼必須以區號開頭,如 +86 或 +852')
}
if (!isPhoneValid && !isEmailValid) {
return new Error('聯繫方式必須是有效的手機號碼或電子郵件')
}
return
},
},
})
const customizeSubmitBtnLoading = ref(false)
function handleCustomizeInfoSubmit() {
customizeInfoFormRef.value?.validate((errors) => {
if (errors) return ''
customizeSubmitBtnLoading.value = true
console.log(customizeInfoForm.value)
customizeSubmitBtnLoading.value = false
isShowVoiceCharacterCustomizeModal.value = false
window.$message.success('提交成功')
})
}
function onModalAfterLeave() {
customizeInfoFormRef.value?.restoreValidation()
customizeInfoForm.value = {
companyName: '',
contactsName: '',
contactInformation: '',
}
}
</script>
<template>
<n-modal v-model:show="isShowVoiceCharacterCustomizeModal" :mask-closable="false" :on-after-leave="onModalAfterLeave">
<n-card
class="!w-[600px]"
title="聲音與數字人形象定制"
:bordered="false"
size="medium"
closable
@close="() => (isShowVoiceCharacterCustomizeModal = false)"
>
<n-form
ref="customizeInfoFormRef"
label-placement="left"
label-width="auto"
:model="customizeInfoForm"
:rules="customizeInfoFormRules"
>
<n-form-item label="公司名稱" path="companyName">
<n-input v-model:value="customizeInfoForm.companyName" placeholder="請輸入公司名稱" />
</n-form-item>
<n-form-item label="聯系人姓名" path="contactsName">
<n-input v-model:value="customizeInfoForm.contactsName" placeholder="請輸入聯系人姓名" />
</n-form-item>
<n-form-item label="聯系方式" path="contactInformation">
<n-input
v-model:value="customizeInfoForm.contactInformation"
placeholder="请输入手机号码(加区号)或电子邮箱"
/>
</n-form-item>
</n-form>
<template #footer>
<div class="text-end">
<n-space justify="end">
<n-button @click="() => (isShowVoiceCharacterCustomizeModal = false)">取消</n-button>
<n-button type="info" :loading="customizeSubmitBtnLoading" @click="handleCustomizeInfoSubmit"
>提交</n-button
>
</n-space>
</div>
</template>
</n-card>
</n-modal>
</template>
......@@ -2,7 +2,8 @@
import { h, ref, shallowReadonly, watchEffect } from 'vue'
import type { MenuOption } from 'naive-ui'
import { useRoute, useRouter } from 'vue-router'
import { Workbench, DocumentFolder, Inbox, CommentOne } from '@icon-park/vue-next'
import { Workbench, DocumentFolder, Inbox, CommentOne, PeopleSpeak } from '@icon-park/vue-next'
import VoiceCharacterCustomize from '../components/voice-character-customize.vue'
const router = useRouter()
const route = useRoute()
......@@ -46,15 +47,32 @@ const menuOptions = shallowReadonly<MenuOption[]>([
},
],
},
{
type: 'group',
label: '定制',
key: 'Customize',
children: [
{
label: '聲音與數字人形象定制',
key: 'VoiceDigitalCharacterCustomize',
icon: () => h(PeopleSpeak, { ...iconConfigFactory() }),
},
],
},
])
const currentMenuValue = ref('')
const isShowViceCharacterCustomizeModal = ref(false)
watchEffect(() => {
currentMenuValue.value = route.name as string
})
function onMenuValueChange(key: string) {
if (key === 'VoiceDigitalCharacterCustomize') {
isShowViceCharacterCustomizeModal.value = true
return
}
router.push({ name: key })
}
</script>
......@@ -69,4 +87,6 @@ function onMenuValueChange(key: string) {
</n-scrollbar>
</div>
</section>
<VoiceCharacterCustomize v-model:is-show-voice-character-customize-modal="isShowViceCharacterCustomizeModal" />
</template>
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