EditForm.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <script setup lang="ts">
  2. import { ElDialog, ElForm, ElFormItem, ElInput, ElDatePicker, ElButton, ElMessage, ElRadio } from 'element-plus'
  3. import type { FormInstance, FormRules } from 'element-plus'
  4. import FaImageUpload from '@/ui/components/FaImageUpload/index.vue'
  5. import { updateVoice } from '@/api/modules/voice'
  6. // 定义表单数据类型
  7. type IFormData = {
  8. "id": string|undefined,
  9. "name": string,
  10. "photoUrl": string,
  11. "feature": string,
  12. "gender": number
  13. }
  14. // 定义组件的属性
  15. interface Props {
  16. visible: boolean
  17. modelValue?: IFormData | null
  18. mode?: 'create' | 'edit'
  19. }
  20. // 定义组件的事件
  21. interface Emits {
  22. (e: 'update:visible', value: boolean): void
  23. (e: 'cancel'): void
  24. (e: 'refresh'): void
  25. }
  26. // 接收属性和事件
  27. const props = withDefaults(defineProps<Props>(), {
  28. visible: false,
  29. modelValue: null,
  30. mode: 'create'
  31. })
  32. const emit = defineEmits<Emits>()
  33. const dialogVisible = computed({
  34. get: () => props.visible,
  35. set: (value) => {
  36. // 这里可以触发一个事件来通知父组件更新 visible 的值
  37. emit('update:visible', value);
  38. },
  39. });
  40. // 表单引用
  41. const editFormRef = ref<FormInstance>();
  42. const photos = ref<string[]>([])
  43. // 响应式数据 - 直接定义所有必需字段
  44. const formData = ref<IFormData>({
  45. photoUrl: '',
  46. name: '',
  47. feature: '',
  48. id: undefined,
  49. gender: 1,
  50. });
  51. // 监听 props.modelValue 变化
  52. watch(() => props.modelValue, (newModelValue) => {
  53. if (newModelValue) {
  54. formData.value = {
  55. ...formData.value,
  56. ...newModelValue
  57. };
  58. console.log(formData.value,newModelValue,4444)
  59. photos.value = newModelValue.photoUrl ? [newModelValue.photoUrl] : []
  60. }
  61. });
  62. // 表单验证规则
  63. const formRules = ref<FormRules>({
  64. name: [
  65. { required: true, message: '请输入名称', trigger: 'blur' },
  66. ],
  67. photoUrl: [
  68. { required: true, message: '请输入描述', trigger: 'blur' },
  69. ],
  70. })
  71. // 监听可见性变化
  72. watch(() => props.visible, (newVisible) => {
  73. if(!newVisible){
  74. resetForm()
  75. }
  76. })
  77. // 重置表单
  78. function resetForm() {
  79. console.log('reset')
  80. if (editFormRef.value) {
  81. editFormRef.value.resetFields()
  82. }
  83. formData.value = {
  84. photoUrl: '',
  85. name: '',
  86. feature: '',
  87. id: undefined,
  88. gender: 1,
  89. }
  90. }
  91. // 处理确认
  92. async function handleConfirm() {
  93. if (!editFormRef.value) return
  94. try {
  95. await editFormRef.value.validate()
  96. const defaultData = {
  97. id: '',
  98. name: '',
  99. photoUrl: '',
  100. feature: '',
  101. gender: 1,
  102. }
  103. const avatar = photos.value?.[0] ?? ''
  104. // 字段全后再对齐字段
  105. //@ts-ignore
  106. const d: any = { ...defaultData, ...formData.value, photoUrl: avatar }
  107. console.log(d)
  108. const { code } = await updateVoice(d)
  109. if (code === 0) {
  110. ElMessage.success('操作成功')
  111. emit('refresh')
  112. }
  113. // 关闭对话框
  114. emit('update:visible', false)
  115. } catch (error) {
  116. // 验证失败,不做处理
  117. }
  118. }
  119. function handleCancel() {
  120. emit('cancel')
  121. emit('update:visible', false)
  122. }
  123. function handleClose() {
  124. emit('update:visible', false)
  125. }
  126. </script>
  127. <template>
  128. <div>
  129. <ElDialog :title="mode === 'create' ? '创建声音' : '编辑声音'" v-model="dialogVisible" align-center @close="handleClose"
  130. width="800" :z-index="2000">
  131. <ElForm ref="editFormRef" :model="formData" :rules="formRules" label-width="120px" class="mt-4 space-y-4 w-full">
  132. <ElFormItem label="name" prop="name" label-width="120">
  133. <ElInput v-model="formData.name" placeholder="Enter name" />
  134. </ElFormItem>
  135. <!-- <ElFormItem label="性别" prop="gender">
  136. <ElRadioGroup v-model="formData.gender">
  137. <ElRadio :value="1">男</ElRadio>
  138. <ElRadio :value="2">女</ElRadio>
  139. <ElRadio :value="3">其他</ElRadio>
  140. </ElRadioGroup>
  141. </ElFormItem> -->
  142. <ElFormItem label="feature" prop="feature" label-width="120">
  143. <ElInput type="textarea" v-model="formData.feature" placeholder="Enter feature" />
  144. </ElFormItem>
  145. <!-- <ElFormItem label="use voice" prop="voiceName" label-width="120">
  146. <LLMSelector v-model="formData.voiceId" />
  147. </ElFormItem> -->
  148. <ElFormItem label="Avatar" prop="avatar" label-width="120">
  149. <FaImageUpload
  150. v-model="photos"
  151. :max-count="1"
  152. list-type="avatar"
  153. />
  154. </ElFormItem>
  155. </ElForm>
  156. <template #footer>
  157. <div class="flex justify-end space-x-2">
  158. <ElButton @click="handleCancel">取消</ElButton>
  159. <ElButton type="primary" @click="handleConfirm">确定</ElButton>
  160. </div>
  161. </template>
  162. </ElDialog>
  163. </div>
  164. </template>