潘志宝
2024-09-09 ed81b7371e376df35448b81531d30dd9024bd44a
提交 | 用户 | 时间
e7c126 1 <template>
H 2   <Dialog :title="dialogTitle" v-model="dialogVisible">
3     <el-form
4       ref="formRef"
5       :model="formData"
6       :rules="formRules"
7       label-width="100px"
8       v-loading="formLoading"
9     >
10       <el-form-item label="名字" prop="name">
11         <el-input v-model="formData.name" placeholder="请输入名字" />
12       </el-form-item>
13       <el-form-item label="简介" prop="description">
14         <el-input v-model="formData.description" type="textarea" placeholder="请输入简介" />
15       </el-form-item>
16       <el-form-item label="出生日期" prop="birthday">
17         <el-date-picker
18           v-model="formData.birthday"
19           type="date"
20           value-format="x"
21           placeholder="选择出生日期"
22         />
23       </el-form-item>
24       <el-form-item label="性别" prop="sex">
25         <el-select v-model="formData.sex" placeholder="请选择性别">
26           <el-option
27             v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
28             :key="dict.value"
29             :label="dict.label"
30             :value="dict.value"
31           />
32         </el-select>
33       </el-form-item>
34       <el-form-item label="是否有效" prop="enabled">
35         <el-radio-group v-model="formData.enabled">
36           <el-radio
37             v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
38             :key="dict.value"
39             :label="dict.value"
40           >
41             {{ dict.label }}
42           </el-radio>
43         </el-radio-group>
44       </el-form-item>
45       <el-form-item label="头像" prop="avatar">
46         <UploadImg v-model="formData.avatar" />
47       </el-form-item>
48       <el-form-item label="附件" prop="video">
49         <UploadFile v-model="formData.video" />
50       </el-form-item>
51       <el-form-item label="备注" prop="memo">
52         <Editor v-model="formData.memo" height="150px" />
53       </el-form-item>
54     </el-form>
55     <template #footer>
56       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
57       <el-button @click="dialogVisible = false">取 消</el-button>
58     </template>
59   </Dialog>
60 </template>
61 <script setup lang="ts">
62 import { getIntDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
63 import * as StudentApi from '@/api/infra/demo'
64
65 const { t } = useI18n() // 国际化
66 const message = useMessage() // 消息弹窗
67
68 const dialogVisible = ref(false) // 弹窗的是否展示
69 const dialogTitle = ref('') // 弹窗的标题
70 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
71 const formType = ref('') // 表单的类型:create - 新增;update - 修改
72 const formData = ref({
73   id: undefined,
74   name: undefined,
75   description: undefined,
76   birthday: undefined,
77   sex: undefined,
78   enabled: undefined,
79   avatar: undefined,
80   video: undefined,
81   memo: undefined,
82 })
83 const formRules = reactive({
84   name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
85   description: [{ required: true, message: '简介不能为空', trigger: 'blur' }],
86   birthday: [{ required: true, message: '出生日期不能为空', trigger: 'blur' }],
87   sex: [{ required: true, message: '性别不能为空', trigger: 'change' }],
88   enabled: [{ required: true, message: '是否有效不能为空', trigger: 'blur' }],
89   avatar: [{ required: true, message: '头像不能为空', trigger: 'blur' }],
90   video: [{ required: true, message: '附件不能为空', trigger: 'blur' }],
91   memo: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
92 })
93 const formRef = ref() // 表单 Ref
94
95 /** 打开弹窗 */
96 const open = async (type: string, id?: number) => {
97   dialogVisible.value = true
98   dialogTitle.value = t('action.' + type)
99   formType.value = type
100   resetForm()
101   // 修改时,设置数据
102   if (id) {
103     formLoading.value = true
104     try {
105       formData.value = await StudentApi.getStudent(id)
106     } finally {
107       formLoading.value = false
108     }
109   }
110 }
111 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
112
113 /** 提交表单 */
114 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
115 const submitForm = async () => {
116   // 校验表单
117   await formRef.value.validate()
118   // 提交请求
119   formLoading.value = true
120   try {
121     const data = formData.value as unknown as StudentApi.StudentVO
122     if (formType.value === 'create') {
123       await StudentApi.createStudent(data)
124       message.success(t('common.createSuccess'))
125     } else {
126       await StudentApi.updateStudent(data)
127       message.success(t('common.updateSuccess'))
128     }
129     dialogVisible.value = false
130     // 发送操作成功的事件
131     emit('success')
132   } finally {
133     formLoading.value = false
134   }
135 }
136
137 /** 重置表单 */
138 const resetForm = () => {
139   formData.value = {
140     id: undefined,
141     name: undefined,
142     description: undefined,
143     birthday: undefined,
144     sex: undefined,
145     enabled: undefined,
146     avatar: undefined,
147     video: undefined,
148     memo: undefined,
149   }
150   formRef.value?.resetFields()
151 }
152 </script>