| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- <script setup lang="ts">
- import { ElDialog, ElForm, ElFormItem, ElInput, ElDatePicker, ElButton, ElMessage, ElRadio } from 'element-plus'
- import type { FormInstance, FormRules } from 'element-plus'
- import FaImageUpload from '@/ui/components/FaImageUpload/index.vue'
- import VoiceSelector from '@/components/VoiceSelector.vue'
- import LangSelector from '@/components/LangSelector.vue'
- import NationalitySelector from '@/components/NationalitySelector.vue'
- import { saveRole } from '@/api/modules/anycallService'
- import type { TSaveRoleParams } from '@/api/modules/anycallService'
- // 定义表单数据类型
- type IFormData = {
- id?: string
- name: string
- photo: string
- prompt: string
- language: string
- languageCode: string
- area: string
- areaCode: string
- gender: number
- description: string
- voiceId: string
- voiceName: string
- }
- // 定义组件的属性
- interface Props {
- visible: boolean
- modelValue?: IFormData | null
- mode?: 'create' | 'edit'
- }
- // 定义组件的事件
- interface Emits {
- (e: 'update:visible', value: boolean): void
- (e: 'cancel'): void
- (e: 'refresh'): void
- }
- // 接收属性和事件
- const props = withDefaults(defineProps<Props>(), {
- visible: false,
- modelValue: null,
- mode: 'create'
- })
- const avatars = ref<string[]>([])
- const emit = defineEmits<Emits>()
- // 创建本地响应式变量用于 v-model 绑定
- const dialogVisible = ref(props.visible)
- // 监听 props.visible 变化,更新本地变量
- watch(() => props.visible, (newVisible) => {
- dialogVisible.value = newVisible
- })
- // 监听本地变量变化,发出 update 事件
- watch(dialogVisible, (newVisible) => {
- emit('update:visible', newVisible)
- })
- // 表单引用
- const editFormRef = ref<FormInstance>();
- const currentSelected = ref<any>(null)
- // 响应式数据 - 直接定义所有必需字段
- const formData = ref<Partial<IFormData> & {voiceId: string, voiceName: string}>({
- name: '',
- photo: '',
- prompt: '',
- language: '',
- languageCode: '',
- area: '',
- areaCode: '',
- description: '',
- gender: 1,
- voiceId: '',
- voiceName: '',
- });
- // 监听 props.modelValue 变化
- watch(() => props.modelValue, (newModelValue) => {
- if (newModelValue) {
- formData.value = {
- ...formData.value,
- ...newModelValue
- };
- avatars.value = newModelValue.photo ? [newModelValue.photo] : []
- }
- });
- // 表单验证规则
- const formRules = ref<FormRules>({
- name: [
- { required: true, message: '请输入名称', trigger: 'blur' },
- ],
- // prompt: [
- // { required: true, message: '请输入 prompt', trigger: 'blur' },
- // ],
- description: [
- { required: true, message: '请输入描述', trigger: 'blur' },
- ],
- // language: [
- // { required: true, message: '请输入语言', trigger: 'blur' },
- // ],
- })
- // 监听可见性变化
- watch(() => props.visible, (newVisible) => {
- if(!newVisible){
- currentSelected.value = null
- resetForm()
- }
- })
- // 重置表单
- function resetForm() {
- console.log('reset')
- if (editFormRef.value) {
- editFormRef.value.resetFields()
- }
- avatars.value = [],
- formData.value = {
- photo: '',
- name: '',
- prompt: '',
- description: '',
- language: '',
- languageCode: '',
- area: '',
- areaCode: '',
- gender: 1,
- voiceId: '',
- voiceName: '',
- }
- }
- // 处理确认
- async function handleConfirm() {
- if (!editFormRef.value) return
- try {
- await editFormRef.value.validate()
- const defaultData = {
- // Matches TSaveRoleParams
- id: formData.value.id,
- name: formData.value.name ?? '',
- voiceId: formData.value.voiceId ?? '',
- language: formData.value.language ?? '',
- languageCode: formData.value.languageCode ?? '',
- area: formData.value.area ?? '',
- areaCode: formData.value.areaCode ?? '',
- description: formData.value.description ?? '',
- prompt: formData.value.prompt ?? '',
- photo: '',
- gender: formData.value.gender ?? 1,
- }
- const avatar = avatars.value?.[0] ?? ''
- // 字段全后再对齐字段
- //@ts-ignore
- const d: TSaveRoleParams = { ...defaultData, photo: avatar }
- console.log(d)
- const { code } = await saveRole(d)
- if (code === 0) {
- ElMessage.success('创建成功')
- emit('refresh')
- }
- // 关闭对话框
- emit('update:visible', false)
- } catch (error) {
- // 验证失败,不做处理
- }
- }
- function handleCancel() {
- emit('cancel')
- emit('update:visible', false)
- }
- function handleClose() {
- emit('update:visible', false)
- }
- const handleSelectorConfirm = (selected: any) => {
- console.log(selected)
- if (selected) {
- }
- }
- const handleRemoveAgent = ()=> {
- currentSelected.value = null
- }
- </script>
- <template>
- <div>
- <ElDialog :title="mode === 'create' ? '创建角色' : '编辑角色'" v-model="dialogVisible" align-center @close="handleClose"
- width="800" :z-index="2000">
- <ElForm ref="editFormRef" :model="formData" :rules="formRules" label-width="120px" class="mt-4 space-y-4 w-full">
- <ElFormItem label="name" prop="name" label-width="120">
- <ElInput v-model="formData.name" placeholder="Enter name" />
- </ElFormItem>
- <ElFormItem label="性别" prop="gender">
- <ElRadioGroup v-model="formData.gender">
- <ElRadio :value="1">男</ElRadio>
- <ElRadio :value="2">女</ElRadio>
- <ElRadio :value="3">其他</ElRadio>
- </ElRadioGroup>
- </ElFormItem>
- <ElFormItem label="prompt" prop="prompt" label-width="120">
- <ElInput type="textarea" v-model="formData.prompt" placeholder="Enter prompt" />
- </ElFormItem>
- <ElFormItem label="description" prop="description" label-width="120">
- <ElInput type="textarea" v-model="formData.description" placeholder="Enter description" />
- </ElFormItem>
- <ElFormItem label="音色" prop="voice" label-width="120">
- <VoiceSelector :gender="formData.gender ?? 1" v-model="formData.voiceId" v-model:voice-name="formData.voiceName" />
- </ElFormItem>
- <ElFormItem label="Avatar" prop="photo" label-width="120">
- <FaImageUpload
- v-model="avatars"
- :max-count="1"
- list-type="avatar"
- />
- </ElFormItem>
- <ElFormItem label="区域" prop="区域">
- <NationalitySelector v-model="formData.areaCode" v-model:key="formData.area" placeholder="区域"></NationalitySelector>
- </ElFormItem>
- <ElFormItem label="语言" prop="language">
- <LangSelector v-model="formData.languageCode" v-model:key="formData.language" placeholder="请选择语言"></LangSelector>
- </ElFormItem>
- </ElForm>
- <template #footer>
- <div class="flex justify-end space-x-2">
- <ElButton @click="handleCancel">取消</ElButton>
- <ElButton type="primary" @click="handleConfirm">确定</ElButton>
- </div>
- </template>
- </ElDialog>
- </div>
- </template>
|